/* SPDX-License-Identifier: GPL-2.0-only */

#include <commonlib/bsd/helpers.h>
#include <console/console.h>
#include <device/device.h>
#include <memrange.h>
#include <post.h>
#include <types.h>

static const char *resource2str(const struct resource *res)
{
	if (res->flags & IORESOURCE_IO)
		return "io";
	if (res->flags & IORESOURCE_PREFETCH)
		return "prefmem";
	if (res->flags & IORESOURCE_MEM)
		return "mem";
	return "undefined";
}

static void print_domain_res(const struct device *dev,
			     const struct resource *res, const char *suffix)
{
	printk(BIOS_DEBUG, "%s %s: base: %llx size: %llx align: %u gran: %u limit: %llx%s\n",
	       dev_path(dev), resource2str(res), res->base, res->size,
	       res->align, res->gran, res->limit, suffix);
}

#define res_printk(depth, str, ...)	printk(BIOS_DEBUG, "%*c"str, depth, ' ', __VA_ARGS__)

static void print_bridge_res(const struct device *dev, const struct resource *res,
			     int depth, const char *suffix)
{
	res_printk(depth, "%s %s: size: %llx align: %u gran: %u limit: %llx%s\n", dev_path(dev),
		   resource2str(res), res->size, res->align, res->gran, res->limit, suffix);
}

static void print_child_res(const struct device *dev, const struct resource *res, int depth)
{
	res_printk(depth + 1, "%s %02lx *  [0x%llx - 0x%llx] %s\n", dev_path(dev),
		   res->index, res->base, res->base + res->size - 1, resource2str(res));
}

static void print_fixed_res(const struct device *dev,
			    const struct resource *res, const char *prefix)
{
	printk(BIOS_DEBUG, " %s: %s %02lx base %08llx limit %08llx %s (fixed)\n",
	       prefix, dev_path(dev), res->index, res->base, res->base + res->size - 1,
	       resource2str(res));
}

static void print_assigned_res(const struct device *dev, const struct resource *res)
{
	printk(BIOS_DEBUG, "  %s %02lx *  [0x%llx - 0x%llx] limit: %llx %s\n",
	       dev_path(dev), res->index, res->base, res->limit, res->limit, resource2str(res));
}

static void print_failed_res(const struct device *dev, const struct resource *res)
{
	printk(BIOS_DEBUG, "  %s %02lx *  size: 0x%llx limit: %llx %s\n",
	       dev_path(dev), res->index, res->size, res->limit, resource2str(res));
}

static void print_resource_ranges(const struct device *dev, const struct memranges *ranges)
{
	const struct range_entry *r;

	printk(BIOS_INFO, " %s: Resource ranges:\n", dev_path(dev));

	if (memranges_is_empty(ranges))
		printk(BIOS_INFO, " * EMPTY!!\n");

	memranges_each_entry(r, ranges) {
		printk(BIOS_INFO, " * Base: %llx, Size: %llx, Tag: %lx\n",
		       range_entry_base(r), range_entry_size(r), range_entry_tag(r));
	}
}

static bool dev_has_children(const struct device *dev)
{
	const struct bus *bus = dev->downstream;
	return bus && bus->children;
}

static resource_t effective_limit(const struct resource *const res)
{
	if (CONFIG(ALWAYS_ALLOW_ABOVE_4G_ALLOCATION))
		return res->limit;

	/* Always allow bridge resources above 4G. */
	if (res->flags & IORESOURCE_BRIDGE)
		return res->limit;

	const resource_t quirk_4g_limit =
		res->flags & IORESOURCE_ABOVE_4G ? UINT64_MAX : UINT32_MAX;
	return MIN(res->limit, quirk_4g_limit);
}

/*
 * During pass 1, once all the requirements for downstream devices of a
 * bridge are gathered, this function calculates the overall resource
 * requirement for the bridge. It starts by picking the largest resource
 * requirement downstream for the given resource type and works by
 * adding requirements in descending order.
 *
 * Additionally, it takes alignment and limits of the downstream devices
 * into consideration and ensures that they get propagated to the bridge
 * resource. This is required to guarantee that the upstream bridge/
 * domain honors the limit and alignment requirements for this bridge
 * based on the tightest constraints downstream.
 *
 * Last but not least, it stores the offset inside the bridge resource
 * for each child resource in its base field. This simplifies pass 2
 * for resources behind a bridge, as we only have to add offsets to the
 * allocated base of the bridge resource.
 */
static void update_bridge_resource(const struct device *bridge, struct resource *bridge_res,
				   int print_depth)
{
	const struct device *child;
	struct resource *child_res;
	resource_t base;
	const unsigned long type_mask = IORESOURCE_TYPE_MASK | IORESOURCE_PREFETCH;
	const unsigned long type_match = bridge_res->flags & type_mask;
	struct bus *bus = bridge->downstream;

	child_res = NULL;

	/*
	 * `base` keeps track of where the next allocation for child resources
	 * can take place from within the bridge resource window. Since the
	 * bridge resource window allocation is not performed yet, it can start
	 * at 0. Base gets updated every time a resource requirement is
	 * accounted for in the loop below. After scanning all these resources,
	 * base will indicate the total size requirement for the current bridge
	 * resource window.
	 */
	base = 0;

	print_bridge_res(bridge, bridge_res, print_depth, "");

	while ((child = largest_resource(bus, &child_res, type_mask, type_match))) {
		/* Size 0 resources can be skipped. */
		if (!child_res->size)
			continue;

		/* Resources with 0 limit can't be assigned anything. */
		if (!child_res->limit)
			continue;

		/*
		 * Propagate the resource alignment to the bridge resource. The
		 * condition can only be true for the first (largest) resource. For all
		 * other child resources, alignment is taken care of by rounding their
		 * base up.
		 */
		if (child_res->align > bridge_res->align)
			bridge_res->align = child_res->align;

		/*
		 * Propagate the resource limit to the bridge resource. If a downstream
		 * device has stricter requirements w.r.t. limits for any resource, that
		 * constraint needs to be propagated back up to the bridges downstream
		 * of the domain. This way, the whole bridge resource fulfills the limit.
		 */
		if (effective_limit(child_res) < bridge_res->limit)
			bridge_res->limit = effective_limit(child_res);

		/*
		 * Alignment value of 0 means that the child resource has no alignment
		 * requirements and so the base value remains unchanged here.
		 */
		base = ALIGN_UP(base, POWER_OF_2(child_res->align));

		/*
		 * Store the relative offset inside the bridge resource for later
		 * consumption in allocate_bridge_resources(), and invalidate flags
		 * related to the base.
		 */
		child_res->base = base;
		child_res->flags &= ~(IORESOURCE_ASSIGNED | IORESOURCE_STORED);

		print_child_res(child, child_res, print_depth);

		base += child_res->size;
	}

	/*
	 * After all downstream device resources are scanned, `base` represents
	 * the total size requirement for the current bridge resource window.
	 * This size needs to be rounded up to the granularity requirement of
	 * the bridge to ensure that the upstream bridge/domain allocates big
	 * enough window.
	 */
	bridge_res->size = ALIGN_UP(base, POWER_OF_2(bridge_res->gran));

	print_bridge_res(bridge, bridge_res, print_depth, " done");
}

/*
 * During pass 1, at the bridge level, the resource allocator gathers
 * requirements from downstream devices and updates its own resource
 * windows for the provided resource type.
 */
static void compute_bridge_resources(const struct device *bridge, unsigned long type_match,
				     int print_depth)
{
	const struct device *child;
	struct resource *res;
	struct bus *bus = bridge->downstream;
	const unsigned long type_mask = IORESOURCE_TYPE_MASK | IORESOURCE_PREFETCH;

	for (res = bridge->resource_list; res; res = res->next) {
		if (!(res->flags & IORESOURCE_BRIDGE))
			continue;

		if ((res->flags & type_mask) != type_match)
			continue;

		/*
		 * Ensure that the resource requirements for all downstream bridges are
		 * gathered before updating the window for current bridge resource.
		 */
		for (child = bus->children; child; child = child->sibling) {
			if (!dev_has_children(child))
				continue;
			compute_bridge_resources(child, type_match, print_depth + 1);
		}

		/*
		 * Update the window for current bridge resource now that all downstream
		 * requirements are gathered.
		 */
		update_bridge_resource(bridge, res, print_depth);
	}
}

/*
 * During pass 1, the resource allocator walks down the entire sub-tree
 * of a domain. It gathers resource requirements for every downstream
 * bridge by looking at the resource requests of its children. Thus, the
 * requirement gathering begins at the leaf devices and is propagated
 * back up to the downstream bridges of the domain.
 *
 * At the domain level, it identifies every downstream bridge and walks
 * down that bridge to gather requirements for each resource type i.e.
 * i/o, mem and prefmem. Since bridges have separate windows for mem and
 * prefmem, requirements for each need to be collected separately.
 *
 * Domain resource windows are fixed ranges and hence requirement
 * gathering does not result in any changes to these fixed ranges.
 */
static void compute_domain_resources(const struct device *domain)
{
	const struct device *child;
	const int print_depth = 1;

	if (domain->downstream == NULL)
		return;

	for (child = domain->downstream->children; child; child = child->sibling) {
		/* Skip if this is not a bridge or has no children under it. */
		if (!dev_has_children(child))
			continue;

		compute_bridge_resources(child, IORESOURCE_IO, print_depth);
		compute_bridge_resources(child, IORESOURCE_MEM, print_depth);
		compute_bridge_resources(child, IORESOURCE_MEM | IORESOURCE_PREFETCH,
					 print_depth);
	}
}

/*
 * Scan the entire tree to identify any fixed resources allocated by
 * any device to ensure that the address map for domain resources are
 * appropriately updated.
 *
 * Domains can typically provide a memrange for entire address space.
 * So, this function punches holes in the address space for all fixed
 * resources that are already defined. Both I/O and normal memory
 * resources are added as fixed. Both need to be removed from address
 * space where dynamic resource allocations are sourced.
 */
static void avoid_fixed_resources(struct memranges *ranges, const struct device *dev,
				  unsigned long mask_match)
{
	const struct resource *res;
	const struct device *child;
	const struct bus *bus;

	for (res = dev->resource_list; res != NULL; res = res->next) {
		if ((res->flags & mask_match) != mask_match)
			continue;
		if (!res->size)
			continue;
		print_fixed_res(dev, res, __func__);
		memranges_create_hole(ranges, res->base, res->size);
	}

	bus = dev->downstream;
	if (bus == NULL)
		return;

	for (child = bus->children; child != NULL; child = child->sibling)
		avoid_fixed_resources(ranges, child, mask_match);
}

/*
 * This function creates a list of memranges of given type using the
 * resource that is provided. It applies additional constraints to
 * ensure that the memranges do not overlap any of the fixed resources
 * under the domain. The domain typically provides a memrange for the
 * entire address space. Thus, it is up to the chipset to add DRAM and
 * all other windows which cannot be used for resource allocation as
 * fixed resources.
 */
static void setup_resource_ranges(const struct device *const domain,
				  const unsigned long type,
				  struct memranges *const ranges)
{
	/* Align mem resources to 2^12 (4KiB pages) at a minimum, so they
	   can be memory-mapped individually (e.g. for virtualization guests). */
	const unsigned char alignment = type == IORESOURCE_MEM ? 12 : 0;
	const unsigned long type_mask = IORESOURCE_TYPE_MASK | IORESOURCE_FIXED;

	memranges_init_empty_with_alignment(ranges, NULL, 0, alignment);

	for (struct resource *res = domain->resource_list; res != NULL; res = res->next) {
		if ((res->flags & type_mask) != type)
			continue;
		print_domain_res(domain, res, "");
		memranges_insert(ranges, res->base, res->limit - res->base + 1, type);
	}

	if (type == IORESOURCE_IO) {
		/*
		 * Don't allow allocations in the VGA I/O range. PCI has special
		 * cases for that.
		 */
		memranges_create_hole(ranges, 0x3b0, 0x3df - 0x3b0 + 1);

		/*
		 * Resource allocator no longer supports the legacy behavior where
		 * I/O resource allocation is guaranteed to avoid aliases over legacy
		 * PCI expansion card addresses.
		 */
	}

	avoid_fixed_resources(ranges, domain, type | IORESOURCE_FIXED);

	print_resource_ranges(domain, ranges);
}

static void cleanup_domain_resource_ranges(const struct device *dev, struct memranges *ranges,
					   unsigned long type)
{
	memranges_teardown(ranges);
	for (struct resource *res = dev->resource_list; res != NULL; res = res->next) {
		if (res->flags & IORESOURCE_FIXED)
			continue;
		if ((res->flags & IORESOURCE_TYPE_MASK) != type)
			continue;
		print_domain_res(dev, res, " done");
	}
}

static void assign_resource(struct resource *const res, const resource_t base,
			    const struct device *const dev)
{
	res->base = base;
	res->limit = res->base + res->size - 1;
	res->flags |= IORESOURCE_ASSIGNED;
	res->flags &= ~IORESOURCE_STORED;

	print_assigned_res(dev, res);
}

/*
 * This is where the actual allocation of resources happens during
 * pass 2. We construct a list of memory ranges corresponding to the
 * resource of a given type, then look for the biggest unallocated
 * resource on the downstream bus. This continues in a descending order
 * until all resources of a given type have space allocated within the
 * domain's resource window.
 */
static void allocate_toplevel_resources(const struct device *const domain,
					const unsigned long type)
{
	const unsigned long type_mask = IORESOURCE_TYPE_MASK;
	struct resource *res = NULL;
	const struct device *dev;
	struct memranges ranges;
	resource_t base;

	if (!dev_has_children(domain))
		return;

	setup_resource_ranges(domain, type, &ranges);

	while ((dev = largest_resource(domain->downstream, &res, type_mask, type))) {
		if (!res->size)
			continue;

		if (!memranges_steal(&ranges, effective_limit(res), res->size, res->align,
				     type, &base, CONFIG(RESOURCE_ALLOCATION_TOP_DOWN))) {
			printk(BIOS_ERR, "Resource didn't fit!!!\n");
			print_failed_res(dev, res);
			continue;
		}

		assign_resource(res, base, dev);
	}

	cleanup_domain_resource_ranges(domain, &ranges, type);
}

/*
 * Pass 2 of the resource allocator at the bridge level loops through
 * all the resources for the bridge and assigns all the base addresses
 * of its children's resources of the same type. update_bridge_resource()
 * of pass 1 pre-calculated the offsets of these bases inside the bridge
 * resource. Now that the bridge resource is allocated, all we have to
 * do is to add its final base to these offsets.
 *
 * Once allocation at the current bridge is complete, resource allocator
 * continues walking down the downstream bridges until it hits the leaf
 * devices.
 */
static void assign_resource_cb(void *param, struct device *dev, struct resource *res)
{
	/* We have to filter the same resources as update_bridge_resource(). */
	if (!res->size || !res->limit)
		return;

	assign_resource(res, *(const resource_t *)param + res->base, dev);
}
static void allocate_bridge_resources(const struct device *bridge)
{
	const unsigned long type_mask =
		IORESOURCE_TYPE_MASK | IORESOURCE_PREFETCH | IORESOURCE_FIXED;
	struct bus *const bus = bridge->downstream;
	struct resource *res;
	struct device *child;

	for (res = bridge->resource_list; res != NULL; res = res->next) {
		if (!res->size)
			continue;

		if (!(res->flags & IORESOURCE_BRIDGE))
			continue;

		if (!(res->flags & IORESOURCE_ASSIGNED))
			continue;

		/* Run assign_resource_cb() for all downstream resources of the same type. */
		search_bus_resources(bus, type_mask, res->flags & type_mask,
				     assign_resource_cb, &res->base);
	}

	for (child = bus->children; child != NULL; child = child->sibling) {
		if (!dev_has_children(child))
			continue;

		allocate_bridge_resources(child);
	}
}

/*
 * Pass 2 of resource allocator begins at the domain level. Every domain
 * has two types of resources - io and mem. For each of these resources,
 * this function creates a list of memory ranges that can be used for
 * downstream resource allocation. This list is constrained to remove
 * any fixed resources in the domain sub-tree of the given resource
 * type. It then uses the memory ranges to apply best fit on the
 * resource requirements of the downstream devices.
 *
 * Once resources are allocated to all downstream devices of the domain,
 * it walks down each downstream bridge to finish resource assignment
 * of its children resources within its own window.
 */
static void allocate_domain_resources(const struct device *domain)
{
	/* Resource type I/O */
	allocate_toplevel_resources(domain, IORESOURCE_IO);

	/*
	 * Resource type 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.
	 */
	allocate_toplevel_resources(domain, IORESOURCE_MEM);

	struct device *child;
	for (child = domain->downstream->children; child; child = child->sibling) {
		if (!dev_has_children(child))
			continue;

		/* Continue allocation for all downstream bridges. */
		allocate_bridge_resources(child);
	}
}

/*
 * This function forms the guts of the resource allocator. It walks
 * through the entire device tree for each domain two times.
 *
 * Every domain has a fixed set of ranges. 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 order to identify the requirements of downstream devices, resource
 * allocator walks in a DFS fashion. It gathers the requirements from
 * leaf devices and propagates those back up to their upstream bridges
 * until the requirements for all the downstream devices of the domain
 * are gathered. This is referred to as pass 1 of the resource allocator.
 *
 * Once the requirements for all the devices under the domain are
 * gathered, the resource allocator walks a second time to allocate
 * resources to downstream devices as per the requirements. It always
 * picks the biggest resource request as per the type (i/o and mem) to
 * allocate space from its fixed window to the immediate downstream
 * device of the domain. In order to accomplish best fit for the
 * resources, a list of ranges is maintained by each resource type (i/o
 * and mem). At the domain level we don't differentiate between mem and
 * prefmem. Since they are allocated space from the same window, the
 * resource allocator at the domain level ensures that the biggest
 * requirement is selected independent of the prefetch type. Once the
 * resource allocation for all immediate downstream devices is complete
 * at the domain level, the resource allocator walks down the subtree
 * for each downstream bridge to continue the allocation process at the
 * bridge level. Since bridges have either their whole window allocated
 * or nothing, we only need to place downstream resources inside these
 * windows by re-using offsets that were pre-calculated in pass 1. This
 * continues until resource allocation is realized for all downstream
 * bridges in the domain sub-tree. This is referred to as pass 2 of the
 * resource allocator.
 *
 * Some rules that are followed by the resource allocator:
 *  - Allocate resource locations for every device as long as
 *    the requirements can be satisfied.
 *  - Don't overlap with resources in fixed locations.
 *  - Don't overlap and follow the rules of bridges -- downstream
 *    devices of bridges should use parts of the address space
 *    allocated to the bridge.
 */
void allocate_resources(const struct device *root)
{
	const struct device *child;

	if ((root == NULL) || (root->downstream == NULL))
		return;

	for (child = root->downstream->children; child; child = child->sibling) {
		if (child->path.type != DEVICE_PATH_DOMAIN)
			continue;

		post_log_path(child);

		/* Pass 1 - Relative placement. */
		printk(BIOS_INFO, "=== Resource allocator: %s - Pass 1 (relative placement) ===\n",
		       dev_path(child));
		compute_domain_resources(child);

		/* Pass 2 - Allocate resources as per gathered requirements. */
		printk(BIOS_INFO, "=== Resource allocator: %s - Pass 2 (allocating resources) ===\n",
		       dev_path(child));
		allocate_domain_resources(child);

		printk(BIOS_INFO, "=== Resource allocator: %s - resource allocation complete ===\n",
		       dev_path(child));
	}
}
