Marc Jones has submitted this change. ( https://review.coreboot.org/c/coreboot/+/46306 )
Change subject: soc/intel/xeon_sp/skx: Add resource allocator helpers ......................................................................
soc/intel/xeon_sp/skx: Add resource allocator helpers
Add and use resource allocator helper functions from cpx. It also simplifies the allocator by removing IORESOURCE_PCI64 from the resource type check. It isn't needed since it is an attribute of IO and MEM and will be added with the appropriate type.
This clean up matches CPX and will help with merging in the future.
Change-Id: I5812b07ba00eeafb4d1e826e9cdf9a659b0248bb Signed-off-by: Marc Jones marcjones@sysproconsulting.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/46306 Reviewed-by: Stefan Reinauer stefan.reinauer@coreboot.org Reviewed-by: Jonathan Zhang jonzhang@fb.com Reviewed-by: Jay Talbott JayTalbott@sysproconsulting.com Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/soc/intel/xeon_sp/skx/chip.c 1 file changed, 90 insertions(+), 38 deletions(-)
Approvals: build bot (Jenkins): Verified Stefan Reinauer: Looks good to me, approved Jay Talbott: Looks good to me, but someone else must approve Jonathan Zhang: Looks good to me, but someone else must approve
diff --git a/src/soc/intel/xeon_sp/skx/chip.c b/src/soc/intel/xeon_sp/skx/chip.c index fba1e1f..7471814 100644 --- a/src/soc/intel/xeon_sp/skx/chip.c +++ b/src/soc/intel/xeon_sp/skx/chip.c @@ -23,6 +23,66 @@ struct stack_dev_resource *next; };
+typedef enum { + RES_TYPE_IO = 0, + RES_TYPE_NONPREF_MEM, + RES_TYPE_PREF_MEM, + MAX_RES_TYPES +} RES_TYPE; + +static RES_TYPE get_res_type(uint64_t flags) +{ + if (flags & IORESOURCE_IO) + return RES_TYPE_IO; + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_PREFETCH) { + printk(BIOS_DEBUG, "%s:%d flags: 0x%llx\n", __func__, __LINE__, flags); + return RES_TYPE_PREF_MEM; + } + /* both 64-bit and 32-bit use below 4GB address space */ + return RES_TYPE_NONPREF_MEM; + } + printk(BIOS_ERR, "Invalid resource type 0x%llx\n", flags); + die(""); +} + +static bool need_assignment(uint64_t flags) +{ + if (flags & (IORESOURCE_STORED | IORESOURCE_RESERVE | IORESOURCE_FIXED | + IORESOURCE_ASSIGNED)) + return false; + else + return true; +} + +static uint64_t get_resource_base(STACK_RES *stack, RES_TYPE res_type) +{ + if (res_type == RES_TYPE_IO) { + assert(stack->PciResourceIoBase <= stack->PciResourceIoLimit); + return stack->PciResourceIoBase; + } + if (res_type == RES_TYPE_NONPREF_MEM) { + assert(stack->PciResourceMem32Base <= stack->PciResourceMem32Limit); + return stack->PciResourceMem32Base; + } + assert(stack->PciResourceMem64Base <= stack->PciResourceMem64Limit); + return stack->PciResourceMem64Base; +} + +static void set_resource_base(STACK_RES *stack, RES_TYPE res_type, uint64_t base) +{ + if (res_type == RES_TYPE_IO) { + assert(base <= (stack->PciResourceIoLimit + 1)); + stack->PciResourceIoBase = base; + } else if (res_type == RES_TYPE_NONPREF_MEM) { + assert(base <= (stack->PciResourceMem32Limit + 1)); + stack->PciResourceMem32Base = base; + } else { + assert(base <= (stack->PciResourceMem64Limit + 1)); + stack->PciResourceMem64Base = base; + } +} + static void assign_stack_resources(struct iiostack_resource *stack_list, struct device *dev, struct resource *bridge);
@@ -167,19 +227,13 @@ } }
-static void reserve_dev_resources(STACK_RES *stack, unsigned long res_type, +static void reserve_dev_resources(STACK_RES *stack, RES_TYPE res_type, struct stack_dev_resource *res_root, struct resource *bridge) { uint8_t align; uint64_t orig_base, base;
- if (res_type & IORESOURCE_IO) - orig_base = stack->PciResourceIoBase; - else if ((res_type & IORESOURCE_MEM) && ((res_type & IORESOURCE_PCI64) || - (!res_root && bridge && (bridge->flags & IORESOURCE_PREFETCH)))) - orig_base = stack->PciResourceMem64Base; - else - orig_base = stack->PciResourceMem32Base; + orig_base = get_resource_base(stack, res_type);
align = 0; base = orig_base; @@ -227,14 +281,7 @@ base = bridge->limit + 1; }
- /* update new limits */ - if (res_type & IORESOURCE_IO) - stack->PciResourceIoBase = base; - else if ((res_type & IORESOURCE_MEM) && ((res_type & IORESOURCE_PCI64) || - (!res_root && bridge && (bridge->flags & IORESOURCE_PREFETCH)))) - stack->PciResourceMem64Base = base; - else - stack->PciResourceMem32Base = base; + set_resource_base(stack, res_type, base); }
static void reclaim_resource_mem(struct stack_dev_resource *res_root) @@ -264,15 +311,14 @@
for (res = dev->resource_list; res; res = res->next) { if (!(res->flags & IORESOURCE_BRIDGE) || - (bridge && ((bridge->flags & (IORESOURCE_IO | IORESOURCE_MEM | - IORESOURCE_PREFETCH | IORESOURCE_PCI64)) != - (res->flags & (IORESOURCE_IO | IORESOURCE_MEM | - IORESOURCE_PREFETCH | IORESOURCE_PCI64))))) + (bridge && (get_res_type(bridge->flags) != get_res_type(res->flags)))) continue;
assign_stack_resources(stack_list, dev, res); + if (!bridge) continue; + /* for 1st time update, overlading IORESOURCE_ASSIGNED */ if (!(bridge->flags & IORESOURCE_ASSIGNED)) { bridge->base = res->base; @@ -308,36 +354,42 @@ assign_bridge_resources(stack_list, curdev, bridge);
/* Pick non-bridged resources for resource allocation for each resource type */ - unsigned long flags[5] = {IORESOURCE_IO, IORESOURCE_MEM, - (IORESOURCE_PCI64|IORESOURCE_MEM), (IORESOURCE_MEM|IORESOURCE_PREFETCH), - (IORESOURCE_PCI64|IORESOURCE_MEM|IORESOURCE_PREFETCH)}; - uint8_t no_res_types = 5; + RES_TYPE res_types[MAX_RES_TYPES] = { + RES_TYPE_IO, + RES_TYPE_NONPREF_MEM, + RES_TYPE_PREF_MEM + }; + + uint8_t no_res_types = MAX_RES_TYPES; + + /* if it is a bridge, only process matching bridge resource type */ if (bridge) { - flags[0] = bridge->flags & - (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH); - if ((bridge->flags & IORESOURCE_MEM) && - (bridge->flags & IORESOURCE_PREFETCH)) - flags[0] |= IORESOURCE_PCI64; + res_types[0] = get_res_type(bridge->flags); no_res_types = 1; }
+ printk(BIOS_DEBUG, "%s:%d no_res_types: %d\n", __func__, __LINE__, + no_res_types); + /* Process each resource type */ for (int rt = 0; rt < no_res_types; ++rt) { struct stack_dev_resource *res_root = NULL; - + printk(BIOS_DEBUG, "%s:%d rt: %d\n", __func__, __LINE__, rt); for (curdev = bus->children; curdev; curdev = curdev->sibling) { struct resource *res; + printk(BIOS_DEBUG, "%s:%d dev: %s\n", + __func__, __LINE__, dev_path(curdev)); if (!curdev->enabled) continue;
for (res = curdev->resource_list; res; res = res->next) { - if ((res->flags & IORESOURCE_BRIDGE) || (res->flags & - (IORESOURCE_STORED | IORESOURCE_RESERVE | - IORESOURCE_FIXED | IORESOURCE_ASSIGNED) - ) || ((res->flags & (IORESOURCE_IO | - IORESOURCE_MEM | IORESOURCE_PCI64 - | IORESOURCE_PREFETCH)) - != flags[rt]) || res->size == 0) + printk(BIOS_DEBUG, "%s:%d dev: %s, flags: 0x%lx\n", + __func__, __LINE__, + dev_path(curdev), res->flags); + if (res->size == 0 || + get_res_type(res->flags) != res_types[rt] || + (res->flags & IORESOURCE_BRIDGE) || + !need_assignment(res->flags)) continue; else add_res_to_stack(&res_root, curdev, res); @@ -346,7 +398,7 @@
/* Allocate resources and update bridge range */ if (res_root || (bridge && !(bridge->flags & IORESOURCE_ASSIGNED))) { - reserve_dev_resources(stack, flags[rt], res_root, bridge); + reserve_dev_resources(stack, res_types[rt], res_root, bridge); reclaim_resource_mem(res_root); } }