Marc Jones has uploaded this change for review. ( 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. This clean up matches CPX and will help with merging in the future.
Change-Id: I5812b07ba00eeafb4d1e826e9cdf9a659b0248bb Signed-off-by: Marc Jones marcjones@sysproconsulting.com --- M src/soc/intel/xeon_sp/skx/chip.c 1 file changed, 90 insertions(+), 38 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/46306/1
diff --git a/src/soc/intel/xeon_sp/skx/chip.c b/src/soc/intel/xeon_sp/skx/chip.c index faa455a..529e07a 100644 --- a/src/soc/intel/xeon_sp/skx/chip.c +++ b/src/soc/intel/xeon_sp/skx/chip.c @@ -22,6 +22,66 @@ struct stack_dev_resource *next; };
+typedef enum { + RES_TYPE_IO = 0, + RES_TYPE_NONPREF_MEM, + RES_TYPE_PREF_MEM, + MAX_RES_TYPES +} ResType; + +static ResType 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("Invalida resource type"); +} + +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, ResType 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, ResType 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);
@@ -166,19 +226,13 @@ } }
-static void reserve_dev_resources(STACK_RES *stack, unsigned long res_type, +static void reserve_dev_resources(STACK_RES *stack, ResType 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; @@ -226,14 +280,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) @@ -263,15 +310,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; @@ -307,36 +353,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; + ResType 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 brigge 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); @@ -345,7 +397,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); } }