From: Justin Sobota Date: Sat, 15 Dec 2012 00:29:19 +0000 (-0500) Subject: Completed and tested routines that automatically reserve linux resources X-Git-Tag: DEV.RM_LLD.02.00.00.01~10^2~26 X-Git-Url: https://git.ti.com/gitweb?p=keystone-rtos%2Frm-lld.git;a=commitdiff_plain;h=0501be2c9e2c2fd57cc89bb55f67406ffa3482c3 Completed and tested routines that automatically reserve linux resources --- diff --git a/device/tci6614-global-resources-mixed.dts b/device/tci6614-global-resources-mixed.dts new file mode 100644 index 0000000..d0df6f1 --- /dev/null +++ b/device/tci6614-global-resources-mixed.dts @@ -0,0 +1,210 @@ +/dts-v1/; + +/ { + device-name = "TCI6614"; + + /* Device Resource Definitions */ + + /* TODO: where do following get defined in the linux DTB + #define ARM_LINUX_CPPI_QMSS_TX_CH_NUM 12 + #define ARM_LINUX_CPPI_QMSS_RX_CH_NUM 12 + #define ARM_LINUX_CPPI_QMSS_FLOW 12 + */ + + qmss { + pdsps { + allocator = "integer"; + resource-range = <0 2>; + }; + memory-regions { + allocator = "integer"; + resource-range = <0 20>; + linux-dtb-alias = "hwqueue@2a00000", "regions", "region-12", "id", "end", <0>, "end"; + }; + link-ram { + allocator = "tree"; + resource-range = <0x00000000 0xFFFFFFFF>; + }; + accumulator-ch { + allocator = "integer"; + resource-range = <0 48>; + /* Each new line specifies a different path. The last string in the line + * must result in a property tied to a value */ + linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-low-0", "accumulator", "end", <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-1", "accumulator", "end", <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-2", "accumulator", "end", <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-3", "accumulator", "end", <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-high", "accumulator", "end", <1>, "end"; + }; + qos-cluster { + allocator = "integer"; + resource-range = <0 8>; + }; + qos-queue { + allocator = "integer"; + resource-range = <0 64>; + }; + + /* Queue definitions based on csl_qm_queue.h */ + low-prio-queue { + allocator = "tree"; + resource-range = <0 512>; + /* Each new line specifies a different path. */ + linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-low-0", "values", "end", <0>, <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-1", "values", "end", <0>, <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-2", "values", "end", <0>, <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-3", "values", "end", <0>, <1>, "end"; + }; + aif-queue { + allocator = "tree"; + resource-range = <512 128>; + }; + pass-queue { + allocator = "integer"; + resource-range = <640 9>; + }; + intc-queue { + allocator = "integer"; + resource-range = <662 10>; + }; + srio-queue { + allocator = "integer"; + resource-range = <672 16>; + linux-dtb-alias = "hwqueue@2a00000", "queues", "riotx", "values", "end", <0>, <1>, "end"; + }; + fftc-a-queue { + allocator = "integer"; + resource-range = <688 4>; + }; + fftc-b-queue { + allocator = "integer"; + resource-range = <692 4>; + }; + bcp-queue { + allocator = "integer"; + resource-range = <864 8>; + }; + high-prio-queue { + allocator = "integer"; + resource-range = <704 32>; + linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-high", "values", "end", <0>, <1>, "end"; + }; + starvation-queue { + allocator = "tree"; + resource-range = <736 64>; + }; + infra-queue { + allocator = "integer"; + resource-range = <800 32>; + linux-dtb-alias = "hwqueue@2a00000", "queues", "infradma", "values", "end", <0>, <1>, "end"; + }; + traffic-shaping-queue { + allocator = "integer"; + resource-range = <832 32>; + }; + gp-queue { + allocator = "tree"; + resource-range = <896 7296>; + linux-dtb-alias = "hwqueue@2a00000", "queues", "general", "values", "end", <0>, <1>, "end"; + }; + }; /* qmss */ + + /* CPPI channel and flow ID ranges based on tci6614 cppi_device.c */ + cppi { + srio-rx-ch { + allocator = "integer"; + resource-range = <0 16>; + }; + srio-tx-ch { + allocator = "integer"; + resource-range = <0 16>; + }; + srio-rx-flow-id { + allocator = "integer"; + resource-range = <0 20>; + }; + + aif-rx-ch { + allocator = "tree"; + resource-range = <0 129>; + }; + aif-tx-ch { + allocator = "tree"; + resource-range = <0 129>; + }; + aif-rx-flow-id { + allocator = "tree"; + resource-range = <0 129>; + }; + + fftc-a-rx-ch { + allocator = "integer"; + resource-range = <0 4>; + }; + fftc-a-tx-ch { + allocator = "integer"; + resource-range = <0 4>; + }; + fftc-a-rx-flow-id { + allocator = "integer"; + resource-range = <0 8>; + }; + + fftc-b-rx-ch { + allocator = "integer"; + resource-range = <0 4>; + }; + fftc-b-tx-ch { + allocator = "integer"; + resource-range = <0 4>; + }; + fftc-b-rx-flow-id { + allocator = "integer"; + resource-range = <0 8>; + }; + + pass-rx-ch { + allocator = "integer"; + resource-range = <0 23>; + }; + pass-tx-ch { + allocator = "integer"; + resource-range = <0 9>; + }; + pass-rx-flow-id { + allocator = "integer"; + resource-range = <0 32>; + }; + + qmss-rx-ch { + allocator = "integer"; + resource-range = <0 32>; + }; + qmss-tx-ch { + allocator = "integer"; + resource-range = <0 32>; + }; + qmss-rx-flow-id { + allocator = "tree"; + resource-range = <0 64>; + }; + + bcp-rx-ch { + allocator = "integer"; + resource-range = <0 8>; + }; + bcp-tx-ch { + allocator = "integer"; + resource-range = <0 8>; + }; + bcp-rx-flow-id { + allocator = "tree"; + resource-range = <0 64>; + }; + }; /* cppi */ + + pa-lut { + allocator = "integer"; + resource-range = <0 5>; + }; +}; \ No newline at end of file diff --git a/device/tci6614-global-resources.dtb b/device/tci6614-global-resources.dtb index c205bd2..4bc70c6 100644 Binary files a/device/tci6614-global-resources.dtb and b/device/tci6614-global-resources.dtb differ diff --git a/device/tci6614-global-resources.dts b/device/tci6614-global-resources.dts index ce56b32..f6b5726 100644 --- a/device/tci6614-global-resources.dts +++ b/device/tci6614-global-resources.dts @@ -13,35 +13,35 @@ qmss { pdsps { - allocator = "integer"; + allocator = "tree"; resource-range = <0 2>; }; memory-regions { - allocator = "integer"; + allocator = "tree"; resource-range = <0 20>; - linux-dtb-alias = "hwqueue0", "regions", "region-12", "id", "end", <0>, "end"; + linux-dtb-alias = "hwqueue@2a00000", "regions", "region-12", "id", "end", <0>, "end"; }; link-ram { allocator = "tree"; resource-range = <0x00000000 0xFFFFFFFF>; }; accumulator-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 48>; /* Each new line specifies a different path. The last string in the line * must result in a property tied to a value */ - linux-dtb-alias = "hwqueue0", "queues", "accumulator-low-0", "accumulator", "end", <1>, "end", - "hwqueue0", "queues", "accumulator-low-1", "accumulator", "end", <1>, "end", - "hwqueue0", "queues", "accumulator-low-2", "accumulator", "end", <1>, "end", - "hwqueue0", "queues", "accumulator-low-3", "accumulator", "end", <1>, "end", - "hwqueue0", "queues", "accumulator-high", "accumulator", "end", <1>, "end"; + linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-low-0", "accumulator", "end", <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-1", "accumulator", "end", <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-2", "accumulator", "end", <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-3", "accumulator", "end", <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-high", "accumulator", "end", <1>, "end"; }; qos-cluster { - allocator = "integer"; + allocator = "tree"; resource-range = <0 8>; }; qos-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <0 64>; }; @@ -50,77 +50,77 @@ allocator = "tree"; resource-range = <0 512>; /* Each new line specifies a different path. */ - linux-dtb-alias = "hwqueue0", "queues", "accumulator-low-0", "values", "end", <0>, <1>, "end", - "hwqueue0", "queues", "accumulator-low-1", "values", "end", <0>, <1>, "end", - "hwqueue0", "queues", "accumulator-low-2", "values", "end", <0>, <1>, "end", - "hwqueue0", "queues", "accumulator-low-3", "values", "end", <0>, <1>, "end"; + linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-low-0", "values", "end", <0>, <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-1", "values", "end", <0>, <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-2", "values", "end", <0>, <1>, "end", + "hwqueue@2a00000", "queues", "accumulator-low-3", "values", "end", <0>, <1>, "end"; }; aif-queue { allocator = "tree"; resource-range = <512 128>; }; pass-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <640 9>; }; intc-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <662 10>; }; srio-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <672 16>; - linux-dtb-alias = "hwqueue0", "queues", "riotx", "values", "end", <0>, <1>, "end"; + linux-dtb-alias = "hwqueue@2a00000", "queues", "riotx", "values", "end", <0>, <1>, "end"; }; fftc-a-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <688 4>; }; fftc-b-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <692 4>; }; bcp-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <864 8>; }; high-prio-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <704 32>; - linux-dtb-alias = "hwqueue0", "queues", "accumulator-high", "values", "end", <0>, <1>, "end"; + linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-high", "values", "end", <0>, <1>, "end"; }; starvation-queue { allocator = "tree"; resource-range = <736 64>; }; infra-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <800 32>; - linux-dtb-alias = "hwqueue0", "queues", "infradma", "values", "end", <0>, <1>, "end"; + linux-dtb-alias = "hwqueue@2a00000", "queues", "infradma", "values", "end", <0>, <1>, "end"; }; traffic-shaping-queue { - allocator = "integer"; + allocator = "tree"; resource-range = <832 32>; }; gp-queue { allocator = "tree"; resource-range = <896 7296>; - linux-dtb-alias = "hwqueue0", "queues", "general", "values", "end", <0>, <1>, "end"; + linux-dtb-alias = "hwqueue@2a00000", "queues", "general", "values", "end", <0>, <1>, "end"; }; }; /* qmss */ /* CPPI channel and flow ID ranges based on tci6614 cppi_device.c */ cppi { srio-rx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 16>; }; srio-tx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 16>; }; srio-rx-flow-id { - allocator = "integer"; + allocator = "tree"; resource-range = <0 20>; }; @@ -138,50 +138,50 @@ }; fftc-a-rx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 4>; }; fftc-a-tx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 4>; }; fftc-a-rx-flow-id { - allocator = "integer"; + allocator = "tree"; resource-range = <0 8>; }; fftc-b-rx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 4>; }; fftc-b-tx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 4>; }; fftc-b-rx-flow-id { - allocator = "integer"; + allocator = "tree"; resource-range = <0 8>; }; pass-rx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 23>; }; pass-tx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 9>; }; pass-rx-flow-id { - allocator = "integer"; + allocator = "tree"; resource-range = <0 32>; }; qmss-rx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 32>; }; qmss-tx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 32>; }; qmss-rx-flow-id { @@ -190,11 +190,11 @@ }; bcp-rx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 8>; }; bcp-tx-ch { - allocator = "integer"; + allocator = "tree"; resource-range = <0 8>; }; bcp-rx-flow-id { @@ -204,7 +204,7 @@ }; /* cppi */ pa-lut { - allocator = "integer"; + allocator = "tree"; resource-range = <0 5>; }; }; diff --git a/include/rm_loc.h b/include/rm_loc.h index 322c7e2..32077e3 100644 --- a/include/rm_loc.h +++ b/include/rm_loc.h @@ -225,8 +225,8 @@ typedef struct _Rm_ResourceTreeNode { char allocatedTo[RM_INSTANCE_NAME_MAX_CHARS]; } Rm_ResourceTreeNode; -/* Will need to malloc a tree of type Rm_ResourceTree for each tree i want to create */ -/* Declare the tree head structure */ +/* Declare the tree head structure. A structure of type Rm_ResourceTree will need to be + * malloc'd for each tree that is to be created. */ typedef RB_HEAD(_Rm_ResourceTree, _Rm_ResourceTreeNode) Rm_ResourceTree; /* Prototype for function that allocates new tree nodes */ diff --git a/src/rm.c b/src/rm.c index 32be8a8..3947f68 100644 --- a/src/rm.c +++ b/src/rm.c @@ -784,7 +784,7 @@ int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_Res /* Create a node in the tree for resource range and insert them into the tree. */ while (range != NULL) { - Rm_newResourceTreeNode(range->base, range->length, RM_NOT_ALLOCATED_STRING); + treeNode = Rm_newResourceTreeNode(range->base, range->length, RM_NOT_ALLOCATED_STRING); /* Insert the node into the tree */ collidingNode = RB_INSERT(_Rm_ResourceTree, treeRootEntry, treeNode); @@ -913,7 +913,7 @@ int32_t Rm_treeAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo) Rm_ResourceTreeNode findNode; Rm_ResourceTreeNode *matchingNode = NULL; Rm_ResourceTreeNode *leftNode = NULL; - Rm_ResourceTreeNode *rightNode = NULL; + Rm_ResourceTreeNode *rightNode = NULL; uint32_t findEnd, matchingEnd; int32_t retVal; @@ -930,117 +930,149 @@ int32_t Rm_treeAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo) /* Does the request range fit within the matching nodes entire range? */ if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) { - /* Handle requested resource range that is isolated to a single node - * - * - * base0 base0+length0-1 - * |<---------------length0------------------->| => existing node - * |<---------length1---------->| => requested resources - * base1 base1+length1-1 - */ + /* Handle node create, combine, deletion based on the request range if + * resources are available. */ if (strcmp(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0) { - /* Resources are available - split up the node into potentially - * three new nodes: - * left node - free resources to left of newly allocated resources - * middle node - newly allocated resources that satisfy the request - * right node - free resources to the right of newly allocated resources + /* Handle case where the findNode range matches the matchingNode + * range exactly. * - * There also may be combine possibilities to the left and right of the - * matching node. Need to extract those as well to check */ - leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); - rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); - - /* Remove the matching node from the tree and the nodes to the left and - * right of the matching node. Removing from tree will not - * wipe any of the base+length data in the node. Can reuse since they won't - * be freed */ - RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); - if (leftNode) + * base0 base0+length0-1 + * |<---------------length0------------------->| => existing node + * |<---------------length1------------------->| => requested resources + * base1 base1+length1-1 + */ + if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) { - RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); + /* Can reserve matchingNode's resources in-place */ + strcpy(matchingNode->allocatedTo, opInfo->srcInstName); } - if (rightNode) + /* Handle case where the findNode range is a subset of the matchingNode + * range and neither of the boundaries of the two ranges are equivalent. + * + * base0 base0+length0-1 + * |<---------------length0------------------->| => existing node + * |<---------length1---------->| => requested resources + * base1 base1+length1-1 + */ + else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) { - RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); - } + /* Split the matching node into three nodes: + * left node - free resources to left of newly allocated resources + * middle node - newly allocated resources that satisfy the request + * right node - free resources to the right of newly allocated resources */ - /* Create the left node if needed. If the bases are equal the matchingNode can - * be reused as the left bound of the range. */ - if (findNode.base > matchingNode->base) - { - /* Can the left node be combined with the node to the left of the matching - * node */ - if (leftNode && (strcmp(leftNode->allocatedTo, opInfo->srcInstName) == 0)) - { - /* Combine the left node and what's leftover on the left side of the - * matchingNode range after the allocation */ - leftNode->length += (findNode.base - matchingNode->base); - } - else + /* Remove the matching node from the tree for modification. */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + + /* New left node attributes: + * base: base of the matching node + * length: base of requested resources - base of matching node */ + leftNode = Rm_newResourceTreeNode(matchingNode->base, findNode.base - matchingNode->base, + RM_NOT_ALLOCATED_STRING); + /* New right node attributes: + * base: base of the requested resources + length of requested resources + * length: right bound of matching node - right bound of request resources */ + rightNode = Rm_newResourceTreeNode(findNode.base + findNode.length, + matchingEnd - findEnd, RM_NOT_ALLOCATED_STRING); + + /* Base and length of matching node become the base and length of the + * requested resources */ + matchingNode->base = findNode.base; + matchingNode->length = findNode.length; + /* Reserve the resources */ + strcpy(matchingNode->allocatedTo, opInfo->srcInstName); + + /* Insert all the nodes */ + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); + } + /* Handle cases where one of findNode range boundaries is equivalent to + * one of the matchingNode range boundaries. + * + * base0 base0+length0-1 + * |<---------------length0------------------->| => existing node + * |<---------length1---------->| => requested resources + * base1 base1+length1-1 + * + * OR + * + * base0 base0+length0-1 + * |<---------------length0------------------->| => existing node + * |<---------length1---------->| => requested resources + * base1 base1+length1-1 + */ + else + { + /* Remove the matchingNode from the tree since it will be edited */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + + if (findNode.base == matchingNode->base) { - /* Reinsert left node and create a new node to left of range to be allocated */ - if (leftNode) + /* There may be a combine possibility to the left. Extract leftNode to check */ + leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + + /* Can the node to the left of the matchingNode be combined with the + * findNode's range? */ + if (leftNode && (strcmp(leftNode->allocatedTo, opInfo->srcInstName) == 0)) + { + /* Remove the leftNode from the tree for editing */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); + + /* Combine the leftNode and the findNode */ + leftNode->length += findNode.length; + } + else { - RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); + /* Allocate a new leftNode that will take the place of the findNode + * range in tree. */ + leftNode = Rm_newResourceTreeNode(findNode.base, findNode.length, + opInfo->srcInstName); } - - /* New left node attributes: - * base: base of the matching node - * length: base of requested resources - base of matching node */ - leftNode = Rm_newResourceTreeNode(matchingNode->base, findNode.base - matchingNode->base, - RM_NOT_ALLOCATED_STRING); - } - } + /* Account for the leftNode in the matchingNode */ + matchingNode->base = findNode.base + findNode.length; + matchingNode->length = matchingEnd - findEnd; - /* Create the right node if needed. If the end ranges are equal the matchingNode - * can be reused as the right bound of the range */ - if (findEnd < matchingEnd) - { - /* Can the right node be combined with the node to the right of the matching - * node */ - if (rightNode && (strcmp(rightNode->allocatedTo, opInfo->srcInstName) == 0)) - { - /* Combine the right node and what's leftover on the right side of the - * matchingNode range after the allocation */ - rightNode->base = findNode.base + findNode.length; - rightNode->length += (matchingEnd - findEnd); + /* Insert the left node */ + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); } - else + else if (findEnd == matchingEnd) { - /* Reinsert right node and create a new node to right of range to be allocated */ - if (rightNode) + /* There may be a combine possibility to the right. Extract rightNode to check */ + rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + + /* Can the node to the right of the matchingNode be combined with the + * findNode's range? */ + if (rightNode && (strcmp(rightNode->allocatedTo, opInfo->srcInstName) == 0)) { - RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); + /* Remove the rightNode from the tree for editing */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); + + /* Combine the rightNode and the findNode */ + rightNode->base = findNode.base; + rightNode->length += findNode.length; + } + else + { + /* Allocate a new rightNode that will take the place of the findNode + * range in tree. */ + rightNode = Rm_newResourceTreeNode(findNode.base, findNode.length, + opInfo->srcInstName); } - - /* New right node attributes: - * base: base of the requested resources + length of requested resources - * length: right bound of matching node - right bound of request resources */ - rightNode = Rm_newResourceTreeNode(findNode.base + findNode.length, - matchingEnd - findEnd, RM_NOT_ALLOCATED_STRING); - } - } - /* Reinsert the left node into the tree if it was modified or created. */ - if (leftNode) - { - RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); - } - /* Reinsert the right node into the tree if it was modified or created. */ - if (rightNode) - { - RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); - } + /* Account for the rightNode in the matchingNode */ + matchingNode->length -= findNode.length; - /* Base and length of matching node becomes the base and length of the requested resources */ - matchingNode->base = findNode.base; - matchingNode->length = findNode.length; - /* Reserve the resources and insert them into the tree */ - strcpy(matchingNode->allocatedTo, opInfo->srcInstName); - RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + /* Insert the right node */ + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); + } + /* Reinsert the edited matching node */ + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + } + retVal = RM_SERVICE_APPROVED_AND_COMPLETED; } else @@ -1117,25 +1149,19 @@ int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo) * wipe any of the base+length data in the node. Can reuse since they won't * be freed */ RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); - if (leftNode) - { - RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); - } - if (rightNode) - { - RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); - } /* See if the left or right or both nodes can be combined with the matching * node that will be freed. */ if (leftNode && (strcmp(leftNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)) { /* Combine the left node and the matching node */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); combineLeft = TRUE; } if (rightNode && (strcmp(rightNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)) { /* Combine the right node and the matching node */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); combineRight = TRUE; } @@ -1181,7 +1207,7 @@ int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo) strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING); RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); } - else + else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) { /* Case 2: free range is less than range in matched node. Need to split * the matched node into three nodes. @@ -1190,44 +1216,112 @@ int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo) * |<---free request--->| */ - /* Create the left node if needed. If the bases are equal the matchingNode can - * be reused as the left bound of the range. */ - if (findNode.base > matchingNode->base) - { - /* New left node attributes: - * base: base of the matching node - * length: base of requested resources - base of matching node */ - leftNode = Rm_newResourceTreeNode(matchingNode->base, findNode.base - matchingNode->base, - matchingNode->allocatedTo); - } + /* Remove matching node for editing. */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); - /* Create the right node if needed. If the end ranges are equal the matchingNode - * can be reused as the right bound of the range */ - if (findEnd < matchingEnd) - { - /* New right node attributes: - * base: base of the requested resources + length of requested resources - * length: right bound of matching node - right bound of request resources */ - rightNode = Rm_newResourceTreeNode(findNode.base + findNode.length, - matchingEnd - findEnd, matchingNode->allocatedTo); - } + /* New left node attributes: + * base: base of the matching node + * length: base of requested resources - base of matching node */ + leftNode = Rm_newResourceTreeNode(matchingNode->base, findNode.base - matchingNode->base, + matchingNode->allocatedTo); + /* New right node attributes: + * base: base of the requested resources + length of requested resources + * length: right bound of matching node - right bound of request resources */ + rightNode = Rm_newResourceTreeNode(findNode.base + findNode.length, + matchingEnd - findEnd, matchingNode->allocatedTo); + + /* Insert the left and right nodes into the tree. */ + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); - /* Insert the left node into the tree if it was created. */ - if (leftNode) + /* Base and length of matching node become the base and length of the freed resources */ + matchingNode->base = findNode.base; + matchingNode->length = findNode.length; + /* Free the resources and insert them into the tree */ + strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING); + RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + } + else + { + /* Remove the matchingNode from the tree since it will be edited */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + + if (findNode.base == matchingNode->base) { + /* Case 3: Free range is on left boundary of matched node. Try to + * combine the free range with the left node if free. + * + * |<---left node (free)--->||<----------matched node---------->| + * |<---findNode (free req)--->| + */ + + /* There may be a combine possibility to the left. Extract leftNode to check */ + leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + + /* Can the node to the left of the matchingNode be combined with the + * findNode's range? */ + if (leftNode && (strcmp(leftNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)) + { + /* Remove the leftNode from the tree for editing */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); + + /* Combine the leftNode and the findNode */ + leftNode->length += findNode.length; + } + else + { + /* Allocate a new leftNode that will take the place of the findNode + * range in tree. */ + leftNode = Rm_newResourceTreeNode(findNode.base, findNode.length, + RM_NOT_ALLOCATED_STRING); + } + + /* Account for the leftNode in the matchingNode */ + matchingNode->base = findNode.base + findNode.length; + matchingNode->length = matchingEnd - findEnd; + + /* Insert the left node */ RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode); } - /* Insert the right node into the tree if it was created. */ - if (rightNode) + else if (findEnd == matchingEnd) { + /* Case 4: Free range is on right boundary of matched node. Try to + * combine the free range with the right node if free. + * + * |<----------matched node---------->||<---right node (free)--->| + * |<---findNode (free req)--->| + */ + + /* There may be a combine possibility to the right. Extract rightNode to check */ + rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); + + /* Can the node to the right of the matchingNode be combined with the + * findNode's range? */ + if (rightNode && (strcmp(rightNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)) + { + /* Remove the rightNode from the tree for editing */ + RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); + + /* Combine the rightNode and the findNode */ + rightNode->base = findNode.base; + rightNode->length += findNode.length; + } + else + { + /* Allocate a new rightNode that will take the place of the findNode + * range in tree. */ + rightNode = Rm_newResourceTreeNode(findNode.base, findNode.length, + RM_NOT_ALLOCATED_STRING); + } + + /* Account for the rightNode in the matchingNode */ + matchingNode->length -= findNode.length; + + /* Insert the right node */ RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); } - /* Base and length of matching node becomes the base and length of the freed resources */ - matchingNode->base = findNode.base; - matchingNode->length = findNode.length; - /* Free the resources and insert them into the tree */ - strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING); + /* Reinsert the edited matching node */ RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); } @@ -1238,7 +1332,6 @@ int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo) /* The matching allocated range to be freed was allocated to a different instance. */ retVal = RM_SERVICE_DENIED_RESOURCE_NOT_ALLOCATED_TO_INSTANCE_REQUESTING_THE_SERVICE; } - } else { @@ -1755,7 +1848,6 @@ int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName const char *propertyName; const void *propertyData; Rm_LinuxValueRange *linuxValueRange; - bool foundResource; int32_t retVal = RM_DTB_UTIL_RESULT_OKAY; /* Initialize the allocator opInfo and resourceInfo structures that will be used to @@ -1765,6 +1857,7 @@ int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName strcpy(resourceInfo.name, resourceName); + /* Set the source instance name for allocation to be the Linux Kernel */ opInfo.srcInstName = RM_ALLOCATED_TO_LINUX; opInfo.operation = Rm_allocatorOp_ALLOCATE; opInfo.resourceInfo = &resourceInfo; @@ -1774,14 +1867,13 @@ int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName while(linuxAlias != NULL) { /* Reset the parsing variables */ - foundResource = FALSE; pathOffset = 0; nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET; prevDepth = RM_DTB_UTIL_STARTING_DEPTH; resourceInfo.base = 0; resourceInfo.length = 0; - while(1) + while(pathOffset < linuxAlias->pathListLenBytes) { /* Move through the DTB nodes until the next alias path node is found */ if (strcmp(linuxAlias->pathList + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL))) @@ -1792,7 +1884,7 @@ int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName { /* Returning from subnode that matched part of alias path without finding * the resource values */ - retVal = (-31); /* TODO: COULD NOT HAVE RESOURCE AT ALIAS PATH */ + retVal = (-31); /* TODO: COULD NOT FIND RESOURCE AT ALIAS PATH */ break; } } @@ -1805,39 +1897,30 @@ int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName /* Check the properties of the node to see if they match the next alias * path string */ propOffset = fdt_first_property_offset(linuxDtb, nodeOffset); - if (propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) - { - /* Search the properties for the next alias path string */ - while (propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) - { - propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, - &propertyName, &propertyLen); + + /* Search the properties for the next alias path string */ + while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && + (pathOffset < linuxAlias->pathListLenBytes)) + { + propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, + &propertyName, &propertyLen); - if (strcmp(linuxAlias->pathList + pathOffset, propertyName) == 0) - { - /* Found the alias property. Extract the values that will - * contain the resource information that must be reserved. */ - linuxValueRange = Rm_linuxExtractValues(propertyData, propertyLen); - /* Use the values to reserve resources for the Linux kernel */ - retVal = Rm_reserveLinuxResource(rmInst, linuxAlias, - linuxValueRange, &opInfo); - - /* Free the memory used to store the values */ - Rm_linuxFreeValues(linuxValueRange); - - foundResource = TRUE; - break; - } + if (strcmp(linuxAlias->pathList + pathOffset, propertyName) == 0) + { + pathOffset += (strlen(linuxAlias->pathList + pathOffset) + 1); + /* Found the alias property. Extract the values that will + * contain the resource information that must be reserved. */ + linuxValueRange = Rm_linuxExtractValues(propertyData, propertyLen); + /* Use the values to reserve resources for the Linux kernel */ + retVal = Rm_reserveLinuxResource(rmInst, linuxAlias, + linuxValueRange, &opInfo); - propOffset = fdt_next_property_offset(linuxDtb, propOffset); - if (propOffset < -FDT_ERR_NOTFOUND) - { - /* Error was returned by LIBFDT when parsing the properties */ - retVal = propOffset; - break; - } - } - } + /* Free the memory used to store the values */ + Rm_linuxFreeValues(linuxValueRange); + } + + propOffset = fdt_next_property_offset(linuxDtb, propOffset); + } if (propOffset < -FDT_ERR_NOTFOUND) { @@ -1845,13 +1928,6 @@ int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName retVal = propOffset; break; } - - if (foundResource) - { - /* Found the resource and reserved it or there was an error - * trying to reserve it. Break out of the while(1) loop */ - break; - } } } @@ -2114,7 +2190,73 @@ int32_t Rm_initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb, void * return(result); } - + +void Rm_printResourceStatus(Rm_Inst *rmInst) +{ + Rm_Allocator *allocator = rmInst->allocators; + Rm_IntegerAllocatorRootEntry *integerRoot; + Rm_IntegerEntry *integerEntry; + Rm_ResourceTree *treeRoot; + Rm_ResourceTreeNode *treeNode; + uint32_t numLinuxResources; + uint32_t i; + + while (allocator != NULL) + { + numLinuxResources = 0; + + Rm_osalLog("Resource: %s\n", allocator->resourceName); + + if (allocator->type == Rm_allocatorType_INTEGER) + { + integerRoot = allocator->allocatorRootEntry; + integerEntry = integerRoot->resourceArrayBase; + + for (i = 0; i < integerRoot->numResourceElements; i++) + { + if (strcmp(integerEntry[i].allocatedTo, RM_ALLOCATED_TO_LINUX) == 0) + { + Rm_osalLog("Value: %5d reserved for %s\n", integerEntry[i].value, + integerEntry[i].allocatedTo); + numLinuxResources++; + } + } + } + else if (allocator->type == Rm_allocatorType_TREE) + { + treeRoot = allocator->allocatorRootEntry; + + RB_FOREACH(treeNode, _Rm_ResourceTree, treeRoot) + { + Rm_osalLog(" %5d - %5d ", treeNode->base, + treeNode->base + treeNode->length -1); + + if (strcmp(treeNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0) + { + Rm_osalLog("NOT ALLOCATED\n"); + } + else + { + Rm_osalLog("allocated to %s\n", treeNode->allocatedTo); + } + + if (strcmp(treeNode->allocatedTo, RM_ALLOCATED_TO_LINUX) == 0) + { + numLinuxResources += treeNode->length; + } + } + } + else + { + Rm_osalLog("Error: Unknown allocator type\n"); + } + + Rm_osalLog("Total allocated to Linux: %d\n", numLinuxResources); + + allocator = allocator->nextAllocator; + } +} + /********************************************************************** ********************** Application visible APIs ********************** **********************************************************************/ @@ -2172,6 +2314,8 @@ Rm_Handle Rm_init(Rm_InitCfg *initCfg) } Rm_initializeAllocators(rmInst, globalResourceDtb, linuxResourceDtb); + + Rm_printResourceStatus(rmInst); } }