/** @file\r
-\r
- DXE Dispatcher Dependency Evaluator\r
+ DXE 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 - 2008, 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
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+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 <DxeMain.h>\r
+#include "DxeMain.h"\r
\r
//\r
// Global stack used to evaluate dependency expressions\r
/**\r
Grow size of the Depex stack\r
\r
- @retval EFI_SUCCESS Stack successfully growed. \r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the \r
- stack.\r
+ @retval EFI_SUCCESS Stack successfully growed.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
GrowDepexStack (\r
VOID\r
Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack);\r
}\r
\r
- NewStack = CoreAllocateBootServicesPool (Size * sizeof (BOOLEAN));\r
+ NewStack = AllocatePool (Size * sizeof (BOOLEAN));\r
if (NewStack == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
// Copy to Old Stack to the New Stack\r
//\r
CopyMem (\r
- NewStack, \r
- mDepexEvaluationStack, \r
+ NewStack,\r
+ mDepexEvaluationStack,\r
(mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (BOOLEAN)\r
);\r
\r
//\r
// Free The Old Stack\r
//\r
- CoreFreePool (mDepexEvaluationStack);\r
+ FreePool (mDepexEvaluationStack);\r
}\r
\r
//\r
\r
\r
/**\r
- Push an element onto the Boolean Stack\r
+ Push an element onto the Boolean Stack.\r
\r
- @param Value BOOLEAN to push. \r
+ @param Value BOOLEAN to push.\r
\r
- @retval EFI_SUCCESS The value was pushed onto the stack. \r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the \r
- stack.\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
PushBool (\r
IN BOOLEAN Value\r
/**\r
Pop an element from the Boolean stack.\r
\r
- @param Value BOOLEAN to pop. \r
+ @param Value BOOLEAN to pop.\r
\r
- @retval EFI_SUCCESS The value was popped onto the stack. \r
- @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
+ @retval EFI_SUCCESS The value was popped onto the stack.\r
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack.\r
\r
**/\r
-STATIC\r
-EFI_STATUS \r
+EFI_STATUS\r
PopBool (\r
OUT BOOLEAN *Value\r
)\r
//\r
mDepexEvaluationStackPointer--;\r
*Value = *mDepexEvaluationStackPointer;\r
- return EFI_SUCCESS; \r
+ return EFI_SUCCESS;\r
}\r
\r
\r
it will be cleared by CoreSchedule(), and then the driver can be\r
dispatched.\r
\r
- @param DriverEntry DriverEntry element to update \r
+ @param DriverEntry DriverEntry element to update .\r
\r
@retval EFI_SUCCESS It always works.\r
\r
**/\r
EFI_STATUS\r
CorePreProcessDepex (\r
- IN EFI_CORE_DRIVER_ENTRY *DriverEntry \r
+ IN EFI_CORE_DRIVER_ENTRY *DriverEntry\r
)\r
{\r
UINT8 *Iterator;\r
- \r
+\r
Iterator = DriverEntry->Depex;\r
if (*Iterator == EFI_DEP_SOR) {\r
DriverEntry->Unrequested = TRUE;\r
} else {\r
DriverEntry->Dependent = TRUE;\r
}\r
- \r
+\r
if (*Iterator == EFI_DEP_BEFORE) {\r
DriverEntry->Before = TRUE;\r
} else if (*Iterator == EFI_DEP_AFTER) {\r
DriverEntry->After = TRUE;\r
- } \r
+ }\r
\r
if (DriverEntry->Before || DriverEntry->After) {\r
CopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID));\r
routine in this case. The SOR is just ignored and is a nop in the grammer.\r
POSTFIX means all the math is done on top of the stack.\r
\r
- @param DriverEntry DriverEntry element to update \r
+ @param DriverEntry DriverEntry element to update.\r
\r
- @retval TRUE If driver is ready to run. \r
- @retval FALSE If driver is not ready to run or some fatal error \r
+ @retval TRUE If driver is ready to run.\r
+ @retval FALSE If driver is not ready to run or some fatal error\r
was found.\r
\r
**/\r
BOOLEAN\r
CoreIsSchedulable (\r
- IN EFI_CORE_DRIVER_ENTRY *DriverEntry \r
+ IN EFI_CORE_DRIVER_ENTRY *DriverEntry\r
)\r
{\r
EFI_STATUS Status;\r
EFI_GUID DriverGuid;\r
VOID *Interface;\r
\r
+ Operator = FALSE;\r
+ Operator2 = FALSE;\r
+\r
if (DriverEntry->After || DriverEntry->Before) {\r
//\r
// If Before or After Depex skip as CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter ()\r
return FALSE;\r
}\r
\r
+ DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));\r
+\r
if (DriverEntry->Depex == NULL) {\r
//\r
// A NULL Depex means treat the driver like an UEFI 2.0 thing.\r
//\r
Status = CoreAllEfiServicesAvailable ();\r
+ DEBUG ((DEBUG_DISPATCH, " All UEFI Services Available = "));\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, "FALSE\n RESULT = FALSE\n"));\r
return FALSE;\r
}\r
+ DEBUG ((DEBUG_DISPATCH, "TRUE\n RESULT = TRUE\n"));\r
return TRUE;\r
}\r
\r
//\r
// Clean out memory leaks in Depex Boolean stack. Leaks are only caused by\r
- // incorrectly formed DEPEX expressions\r
+ // incorrectly formed DEPEX expressions\r
//\r
mDepexEvaluationStackPointer = mDepexEvaluationStack;\r
\r
\r
Iterator = DriverEntry->Depex;\r
- \r
+\r
while (TRUE) {\r
//\r
// Check to see if we are attempting to fetch dependency expression instructions\r
// past the end of the dependency expression.\r
//\r
if (((UINTN)Iterator - (UINTN)DriverEntry->Depex) >= DriverEntry->DepexSize) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Attempt to fetch past end of depex)\n"));\r
return FALSE;\r
}\r
\r
// If the code flow arrives at this point, there was a BEFORE or AFTER\r
// that were not the first opcodes.\r
//\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected BEFORE or AFTER opcode)\n"));\r
ASSERT (FALSE);\r
case EFI_DEP_SOR:\r
//\r
- // These opcodes can only appear once as the first opcode. If it is found \r
+ // These opcodes can only appear once as the first opcode. If it is found\r
// at any other location, then the dependency expression evaluates to FALSE\r
//\r
if (Iterator != DriverEntry->Depex) {\r
+ DEBUG ((DEBUG_DISPATCH, " SOR\n"));\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected SOR opcode)\n"));\r
return FALSE;\r
}\r
+ DEBUG ((DEBUG_DISPATCH, " SOR = Requested\n"));\r
//\r
// Otherwise, it is the first opcode and should be treated as a NOP.\r
//\r
break;\r
\r
- case EFI_DEP_PUSH: \r
+ case EFI_DEP_PUSH:\r
//\r
// Push operator is followed by a GUID. Test to see if the GUID protocol\r
// is installed and push the boolean result on the stack.\r
Status = CoreLocateProtocol (&DriverGuid, NULL, &Interface);\r
\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = FALSE\n", &DriverGuid));\r
Status = PushBool (FALSE);\r
} else {\r
+ DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = TRUE\n", &DriverGuid));\r
*Iterator = EFI_DEP_REPLACE_TRUE;\r
Status = PushBool (TRUE);\r
}\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
\r
Iterator += sizeof (EFI_GUID);\r
break;\r
\r
- case EFI_DEP_AND: \r
+ case EFI_DEP_AND:\r
+ DEBUG ((DEBUG_DISPATCH, " AND\n"));\r
Status = PopBool (&Operator);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
\r
Status = PopBool (&Operator2);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
\r
Status = PushBool ((BOOLEAN)(Operator && Operator2));\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
break;\r
\r
- case EFI_DEP_OR: \r
+ case EFI_DEP_OR:\r
+ DEBUG ((DEBUG_DISPATCH, " OR\n"));\r
Status = PopBool (&Operator);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
\r
Status = PopBool (&Operator2);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
\r
Status = PushBool ((BOOLEAN)(Operator || Operator2));\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
break;\r
\r
- case EFI_DEP_NOT: \r
+ case EFI_DEP_NOT:\r
+ DEBUG ((DEBUG_DISPATCH, " NOT\n"));\r
Status = PopBool (&Operator);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
\r
Status = PushBool ((BOOLEAN)(!Operator));\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
break;\r
\r
- case EFI_DEP_TRUE: \r
+ case EFI_DEP_TRUE:\r
+ DEBUG ((DEBUG_DISPATCH, " TRUE\n"));\r
Status = PushBool (TRUE);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
break;\r
\r
- case EFI_DEP_FALSE: \r
+ case EFI_DEP_FALSE:\r
+ DEBUG ((DEBUG_DISPATCH, " FALSE\n"));\r
Status = PushBool (FALSE);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
break;\r
\r
- case EFI_DEP_END: \r
+ case EFI_DEP_END:\r
+ DEBUG ((DEBUG_DISPATCH, " END\n"));\r
Status = PopBool (&Operator);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = %a\n", Operator ? "TRUE" : "FALSE"));\r
return Operator;\r
\r
case EFI_DEP_REPLACE_TRUE:\r
+ CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID));\r
+ DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = TRUE\n", &DriverGuid));\r
+ \r
Status = PushBool (TRUE);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n"));\r
return FALSE;\r
}\r
\r
Iterator += sizeof (EFI_GUID);\r
break;\r
\r
- default: \r
+ default:\r
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unknown opcode)\n"));\r
goto Done;\r
}\r
- \r
+\r
//\r
// Skip over the Dependency Op Code we just processed in the switch.\r
// The math is done out of order, but it should not matter. That is\r