--- /dev/null
+/** @file\r
+ PEI Dispatcher Dependency Evaluator\r
+\r
+ This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine\r
+ if a driver can be scheduled for execution. The criteria for\r
+ schedulability is that the dependency expression is satisfied.\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+**/\r
+\r
+#include <PeiMain.h>\r
+#include "dependency.h"\r
+\r
+/**\r
+\r
+ This routine determines if a PPI has been installed.\r
+ The truth value of a GUID is determined by if the PPI has\r
+ been published and can be queried from the PPI database.\r
+\r
+\r
+ @param PeiServices The PEI core services table.\r
+ @param Stack Reference to EVAL_STACK_ENTRY that contains PPI GUID to check\r
+\r
+ @retval TRUE if the PPI is already installed.\r
+ @retval FALSE if the PPI has yet to be installed.\r
+\r
+**/\r
+BOOLEAN\r
+IsPpiInstalled (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EVAL_STACK_ENTRY *Stack\r
+ )\r
+{\r
+ VOID *PeiInstance;\r
+ EFI_STATUS Status;\r
+ EFI_GUID PpiGuid;\r
+ \r
+ //\r
+ // If there is no GUID to evaluate, just return current result on stack.\r
+ //\r
+ if (Stack->Operator == NULL) {\r
+ return Stack->Result;\r
+ }\r
+ \r
+ //\r
+ // Copy the Guid into a locale variable so that there are no\r
+ // possibilities of alignment faults for cross-compilation \r
+ // environments such as Intel?Itanium(TM).\r
+ //\r
+ CopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));\r
+\r
+ //\r
+ // Check if the PPI is installed.\r
+ //\r
+ Status = PeiServicesLocatePpi(\r
+ &PpiGuid, // GUID\r
+ 0, // INSTANCE\r
+ NULL, // EFI_PEI_PPI_DESCRIPTOR\r
+ &PeiInstance // PPI\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ return FALSE;\r
+ }\r
+ \r
+ return TRUE;\r
+}\r
+\r
+/**\r
+\r
+ This is the POSTFIX version of the dependency evaluator. When a\r
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on\r
+ the evaluation stack. When that entry is poped from the evaluation\r
+ stack, the PPI is checked if it is installed. This method allows\r
+ some time savings as not all PPIs must be checked for certain\r
+ operation types (AND, OR).\r
+\r
+\r
+ @param PeiServices Calling context.\r
+ @param DependencyExpression Pointer to a dependency expression. The Grammar adheres to\r
+ the BNF described above and is stored in postfix notation.\r
+\r
+ @retval TRUE if it is a well-formed Grammar\r
+ @retval FALSE if the dependency expression overflows the evaluation stack\r
+ if the dependency expression underflows the evaluation stack\r
+ if the dependency expression is not a well-formed Grammar.\r
+\r
+**/\r
+BOOLEAN\r
+PeimDispatchReadiness (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN VOID *DependencyExpression\r
+ )\r
+{\r
+ DEPENDENCY_EXPRESSION_OPERAND *Iterator;\r
+ EVAL_STACK_ENTRY *StackPtr;\r
+ EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];\r
+\r
+ Iterator = DependencyExpression;\r
+\r
+ StackPtr = &EvalStack[0];\r
+\r
+ while (TRUE) {\r
+\r
+ switch (*(Iterator++)) {\r
+ \r
+ //\r
+ // For performance reason we put the frequently used items in front of \r
+ // the rarely used items\r
+ //\r
+ \r
+ case (EFI_DEP_PUSH):\r
+ //\r
+ // Check to make sure the dependency grammar doesn't overflow the\r
+ // EvalStack on the push\r
+ //\r
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)\r
+ // We will evaluate if the PPI is insalled on the POP operation.\r
+ //\r
+ StackPtr->Operator = (VOID *) Iterator;\r
+ Iterator = Iterator + sizeof (EFI_GUID);\r
+ StackPtr++;\r
+ break;\r
+\r
+ case (EFI_DEP_AND): \r
+ case (EFI_DEP_OR): \r
+ //\r
+ // Check to make sure the dependency grammar doesn't underflow the\r
+ // EvalStack on the two POPs for the AND operation. Don't need to\r
+ // check for the overflow on PUSHing the result since we already\r
+ // did two POPs.\r
+ //\r
+ if (StackPtr < &EvalStack[2]) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Evaluate the first POPed operator only. If the operand is\r
+ // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the\r
+ // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,\r
+ // we don't need to check the second operator, and the result will be\r
+ // evaluation of the POPed operator. Otherwise, don't POP the second\r
+ // operator since it will now evaluate to the final result on the\r
+ // next operand that causes a POP.\r
+ // \r
+ StackPtr--;\r
+ //\r
+ // Iterator has increased by 1 after we retrieve the operand, so here we \r
+ // should get the value pointed by (Iterator - 1), in order to obtain the \r
+ // same operand.\r
+ //\r
+ if (*(Iterator - 1) == EFI_DEP_AND) {\r
+ if (!(IsPpiInstalled (PeiServices, StackPtr))) {\r
+ (StackPtr-1)->Result = FALSE;\r
+ (StackPtr-1)->Operator = NULL;\r
+ }\r
+ } else {\r
+ if (IsPpiInstalled (PeiServices, StackPtr)) {\r
+ (StackPtr-1)->Result = TRUE;\r
+ (StackPtr-1)->Operator = NULL;\r
+ }\r
+ }\r
+ break;\r
+ \r
+ case (EFI_DEP_END):\r
+ StackPtr--;\r
+ //\r
+ // Check to make sure EvalStack is balanced. If not, then there is\r
+ // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.\r
+ //\r
+ if (StackPtr != &EvalStack[0]) {\r
+ return FALSE;\r
+ }\r
+ return IsPpiInstalled (PeiServices, StackPtr);\r
+ break;\r
+\r
+ case (EFI_DEP_NOT): \r
+ //\r
+ // Check to make sure the dependency grammar doesn't underflow the\r
+ // EvalStack on the POP for the NOT operation. Don't need to\r
+ // check for the overflow on PUSHing the result since we already\r
+ // did a POP.\r
+ //\r
+ if (StackPtr < &EvalStack[1]) {\r
+ return FALSE;\r
+ }\r
+ (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));\r
+ (StackPtr-1)->Operator = NULL;\r
+ break;\r
+\r
+ case (EFI_DEP_TRUE):\r
+ case (EFI_DEP_FALSE):\r
+ //\r
+ // Check to make sure the dependency grammar doesn't overflow the\r
+ // EvalStack on the push\r
+ //\r
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {\r
+ return FALSE;\r
+ }\r
+ //\r
+ // Iterator has increased by 1 after we retrieve the operand, so here we \r
+ // should get the value pointed by (Iterator - 1), in order to obtain the \r
+ // same operand.\r
+ //\r
+ if (*(Iterator - 1) == EFI_DEP_TRUE) {\r
+ StackPtr->Result = TRUE;\r
+ } else {\r
+ StackPtr->Result = FALSE;\r
+ }\r
+ StackPtr->Operator = NULL;\r
+ StackPtr++;\r
+ break;\r
+\r
+ default:\r
+ //\r
+ // The grammar should never arrive here\r
+ //\r
+ return FALSE;\r
+ break;\r
+ }\r
+ }\r
+}\r
+++ /dev/null
-/** @file\r
- PEI Dispatcher Dependency Evaluator\r
-\r
- This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine\r
- if a driver can be scheduled for execution. The criteria for\r
- schedulability is that the dependency expression is satisfied.\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#include <PeiMain.h>\r
-#include "dependency.h"\r
-\r
-/**\r
-\r
- This routine determines if a PPI has been installed.\r
- The truth value of a GUID is determined by if the PPI has\r
- been published and can be queried from the PPI database.\r
-\r
-\r
- @param PeiServices The PEI core services table.\r
- @param Stack Reference to EVAL_STACK_ENTRY that contains PPI GUID to check\r
-\r
- @retval TRUE if the PPI is already installed.\r
- @retval FALSE if the PPI has yet to be installed.\r
-\r
-**/\r
-BOOLEAN\r
-IsPpiInstalled (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EVAL_STACK_ENTRY *Stack\r
- )\r
-{\r
- VOID *PeiInstance;\r
- EFI_STATUS Status;\r
- EFI_GUID PpiGuid;\r
- \r
- //\r
- // If there is no GUID to evaluate, just return current result on stack.\r
- //\r
- if (Stack->Operator == NULL) {\r
- return Stack->Result;\r
- }\r
- \r
- //\r
- // Copy the Guid into a locale variable so that there are no\r
- // possibilities of alignment faults for cross-compilation \r
- // environments such as Intel?Itanium(TM).\r
- //\r
- CopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));\r
-\r
- //\r
- // Check if the PPI is installed.\r
- //\r
- Status = PeiServicesLocatePpi(\r
- &PpiGuid, // GUID\r
- 0, // INSTANCE\r
- NULL, // EFI_PEI_PPI_DESCRIPTOR\r
- &PeiInstance // PPI\r
- );\r
-\r
- if (EFI_ERROR(Status)) {\r
- return FALSE;\r
- }\r
- \r
- return TRUE;\r
-}\r
-\r
-/**\r
-\r
- This is the POSTFIX version of the dependency evaluator. When a\r
- PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on\r
- the evaluation stack. When that entry is poped from the evaluation\r
- stack, the PPI is checked if it is installed. This method allows\r
- some time savings as not all PPIs must be checked for certain\r
- operation types (AND, OR).\r
-\r
-\r
- @param PeiServices Calling context.\r
- @param DependencyExpression Pointer to a dependency expression. The Grammar adheres to\r
- the BNF described above and is stored in postfix notation.\r
-\r
- @retval TRUE if it is a well-formed Grammar\r
- @retval FALSE if the dependency expression overflows the evaluation stack\r
- if the dependency expression underflows the evaluation stack\r
- if the dependency expression is not a well-formed Grammar.\r
-\r
-**/\r
-BOOLEAN\r
-PeimDispatchReadiness (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN VOID *DependencyExpression\r
- )\r
-{\r
- DEPENDENCY_EXPRESSION_OPERAND *Iterator;\r
- EVAL_STACK_ENTRY *StackPtr;\r
- EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];\r
-\r
- Iterator = DependencyExpression;\r
-\r
- StackPtr = &EvalStack[0];\r
-\r
- while (TRUE) {\r
-\r
- switch (*(Iterator++)) {\r
- \r
- //\r
- // For performance reason we put the frequently used items in front of \r
- // the rarely used items\r
- //\r
- \r
- case (EFI_DEP_PUSH):\r
- //\r
- // Check to make sure the dependency grammar doesn't overflow the\r
- // EvalStack on the push\r
- //\r
- if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)\r
- // We will evaluate if the PPI is insalled on the POP operation.\r
- //\r
- StackPtr->Operator = (VOID *) Iterator;\r
- Iterator = Iterator + sizeof (EFI_GUID);\r
- StackPtr++;\r
- break;\r
-\r
- case (EFI_DEP_AND): \r
- case (EFI_DEP_OR): \r
- //\r
- // Check to make sure the dependency grammar doesn't underflow the\r
- // EvalStack on the two POPs for the AND operation. Don't need to\r
- // check for the overflow on PUSHing the result since we already\r
- // did two POPs.\r
- //\r
- if (StackPtr < &EvalStack[2]) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Evaluate the first POPed operator only. If the operand is\r
- // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the\r
- // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,\r
- // we don't need to check the second operator, and the result will be\r
- // evaluation of the POPed operator. Otherwise, don't POP the second\r
- // operator since it will now evaluate to the final result on the\r
- // next operand that causes a POP.\r
- // \r
- StackPtr--;\r
- //\r
- // Iterator has increased by 1 after we retrieve the operand, so here we \r
- // should get the value pointed by (Iterator - 1), in order to obtain the \r
- // same operand.\r
- //\r
- if (*(Iterator - 1) == EFI_DEP_AND) {\r
- if (!(IsPpiInstalled (PeiServices, StackPtr))) {\r
- (StackPtr-1)->Result = FALSE;\r
- (StackPtr-1)->Operator = NULL;\r
- }\r
- } else {\r
- if (IsPpiInstalled (PeiServices, StackPtr)) {\r
- (StackPtr-1)->Result = TRUE;\r
- (StackPtr-1)->Operator = NULL;\r
- }\r
- }\r
- break;\r
- \r
- case (EFI_DEP_END):\r
- StackPtr--;\r
- //\r
- // Check to make sure EvalStack is balanced. If not, then there is\r
- // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.\r
- //\r
- if (StackPtr != &EvalStack[0]) {\r
- return FALSE;\r
- }\r
- return IsPpiInstalled (PeiServices, StackPtr);\r
- break;\r
-\r
- case (EFI_DEP_NOT): \r
- //\r
- // Check to make sure the dependency grammar doesn't underflow the\r
- // EvalStack on the POP for the NOT operation. Don't need to\r
- // check for the overflow on PUSHing the result since we already\r
- // did a POP.\r
- //\r
- if (StackPtr < &EvalStack[1]) {\r
- return FALSE;\r
- }\r
- (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));\r
- (StackPtr-1)->Operator = NULL;\r
- break;\r
-\r
- case (EFI_DEP_TRUE):\r
- case (EFI_DEP_FALSE):\r
- //\r
- // Check to make sure the dependency grammar doesn't overflow the\r
- // EvalStack on the push\r
- //\r
- if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {\r
- return FALSE;\r
- }\r
- //\r
- // Iterator has increased by 1 after we retrieve the operand, so here we \r
- // should get the value pointed by (Iterator - 1), in order to obtain the \r
- // same operand.\r
- //\r
- if (*(Iterator - 1) == EFI_DEP_TRUE) {\r
- StackPtr->Result = TRUE;\r
- } else {\r
- StackPtr->Result = FALSE;\r
- }\r
- StackPtr->Operator = NULL;\r
- StackPtr++;\r
- break;\r
-\r
- default:\r
- //\r
- // The grammar should never arrive here\r
- //\r
- return FALSE;\r
- break;\r
- }\r
- }\r
-}\r