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>
This commit is contained in:
parent
e1a7a26f5e
commit
0262ffa85c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue