diff options
-rw-r--r-- | src/soc/intel/xeon_sp/skx/chip.c | 128 |
1 files changed, 90 insertions, 38 deletions
diff --git a/src/soc/intel/xeon_sp/skx/chip.c b/src/soc/intel/xeon_sp/skx/chip.c index fba1e1f7d0..7471814fa0 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 { 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 add_res_to_stack(struct stack_dev_resource **root, } } -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 @@ static void reserve_dev_resources(STACK_RES *stack, unsigned long res_type, 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 @@ static void assign_bridge_resources(struct iiostack_resource *stack_list, 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 @@ static void assign_stack_resources(struct iiostack_resource *stack_list, 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 @@ static void assign_stack_resources(struct iiostack_resource *stack_list, /* 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); } } |