This patch tunes MTX_TABLES into a leaf lock by always ensuring it is
released before holding other locks.
This patch also collects all table loading related functions into
AcpiTbLoadTable() (invoked by LoadTable opcode) and
AcpiTbInstallAndLoadTable() (invoked by Load opcode and AcpiLoadTable()) so
that we can have lock tuning code collected at the boundary of these 2
functions. Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
This patch fixes an issue with AcpiDsAutoSerializedMethod().
The parser will invoke AcpiExReleaseAllMutexes(), which in return
cause mutexes held in ACPI_ERROR_METHOD() failed. Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
There are issues related to the namespace/interpreter locks, which causes
several ACPI functionalities not specification compliant.
Let's first look into the namespace/interpreter lock usages inside of the
object evaluation and the table loading which are the key AML interpretion
code paths:
Table loading:
AcpiNsLoadTable
L(Namespace)
AcpiNsParseTable
AcpiNsOneCompleteParse(LOAD_PASS1/LOAD_PASS2)
AcpiDsLoad1BegionOp
AcpiDsLoad1EndOp
AcpiDsLoad2BegionOp
AcpiDsLoad2EndOp
U(Namespace)
Object evaluation:
AcpiNsEvaluate
L(Interpreter)
AcpiPsExecuteMethod
AcpiDsExecBeginOp
AcpiDsExecEndOp
U(Interpreter)
AcpiNsLoadTable
L(Namespace)
U(Namespace)
AcpiEvInitializeRegion
L(Namespace)
U(Namespace)
AddressSpace.Setup
AddressSpace.Handler
AcpiOsWaitSemaphore
AcpiOsAcquireMutex
AcpiOsSleep
L(Interpreter)
U(Interpreter)
L(Interpreter)
AcpiExResolveNodeToValue
U(Interpreter)
AcpiNsCheckReturnValue
Where:
1. L(Interpreter) means acquire(MTX_INTERPRETER);
2. U(Interpreter) means release(MTX_INTERPRETER);
3. L(Namespace) means acquire(MTX_NAMESPACE);
4. U(Namespace) means release(MTX_NAMESPACE);
We can see that AcpiNsExecModuleCode() (which invokes AcpiNsEvaluate) is
implemented in a deferred way just in order to avoid to reacquire the
namespace lock. This is in fact the root cause of many other ACPICA issues:
1. We now know for sure that the module code should be executed right in
place by the Windows AML interpreter. So in the current design, if
the region initializations/accesses or the table loadings (where the
namespace surely should be locked again) happening during the table
loading period, dead lock could happen because ACPICA never unlocks the
namespace during the AML interpretion.
2. ACPICA interpreter just ensures that all static namespace nodes (named
objects created during the AcpiLoadTables()) are created
(AcpiNsLookup()) with the correct lock held, but doesn't ensure that
the named objects created by the control method are created with the
same correct lock held. It requires the control methods to be executed
in a serial way after "loading a table", that's why ACPICA requires
method auto serialization.
This patch fixes these software design issues by extending interpreter
enter/exit APIs to hold both interpreter/namespace locks to ensure the lock
order correctness, so that we can get these code paths:
Table loading:
AcpiNsLoadTable
E(Interpreter)
AcpiNsParseTable
AcpiNsOneCompleteParse
AcpiNsExecuteTable
X(Interpreter)
AcpiNsLoadTable
AcpiEvInitializeRegion
AddressSpace.Setup
AddressSpace.Handler
AcpiOsWaitSemaphore
AcpiOsAcquireMutex
AcpiOsSleep
E(Interpreter)
X(Interpreter)
Object evaluation:
AcpiNsEvaluate
E(Interpreter)
AcpiPsExecuteMethod
X(Interpreter)
AcpiNsLoadTable
AcpiEvInitializeRegion
AddressSpace.Setup
AddressSpace.Handler
AcpiOsWaitSemaphore
AcpiOsAcquireMutex
AcpiOsSleep
E(Interpreter)
X(Interpreter)
Where:
1. E(Interpreter) means acquire(MTX_INTERPRETER, MTX_NAMESPACE);
2. X(Interpreter) means release(MTX_NAMESPACE, MTX_INTERPRETER);
After this change, we can see:
1. All namespace nodes creations are locked by the namespace lock.
2. All namespace nodes referencing are locked with the same lock.
3. But we also can notice a defact that, all namespace nodes deletions
could be affected by this change. As a consequence,
AcpiNsDeleteNamespaceSubtree() may delete a static namespace node that
is still referenced by the interpreter (for example, the parser scopes).
Currently, we needn't worry about the last defact because in ACPICA, table
unloading is not fully functioning, its design strictly relies on the fact
that when the namespace deletion happens, either the AML table or the OSPMs
should have been notified and thus either the AML table or the OSPMs
shouldn't reference deletion-related namespace nodes during the namespace
deletion. And this change still works with the above restrictions applied.
While making this a-step-forward helps us to correct the wrong grammar to
pull many things back to the correct rail. And pulling things back to the
correct rail in return makes it possible for us to support fully
functioning table unloading after doing many cleanups.
While this patch is generated, all namespace locks are examined to ensure
that they can meet either of the following pattens:
1. L(Namespace)
U(Namespace)
2. E(Interpreter)
X(Interpreter)
3. E(Interpreter)
X(Interpreter)
L(Namespace)
U(Namespace)
E(Interpreter)
X(Interpreter)
We ensure this by adding X(Interpreter)/E(Interpreter) or removing
U(Namespace)/L(Namespace) for those currently are executed in the following
order:
E(Interpreter)
L(Namespace)
U(Namespace)
X(Interpreter)
And adding E(Interpreter)/X(Interpreter) for those currently are executed
in the following order:
X(Interpreter)
E(Interpreter)
Originally, the interpreter lock is held for the execution AML opcodes, the
namespace lock is held for the named object creation AML opcodes. Since
they are actually same in MS interpreter (can all be executed during the
table loading), we can combine the 2 locks and tune the locking code better
in this way. Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
The MLC (Module Level Code) is an ACPICA terminology describing the AML
code out of any control method, its support is an indication of the
interpreter behavior during the table loading.
The original implementation of MLC in ACPICA had several issues:
1. Out of any control method, besides of the object creating opcodes, only
the code blocks wrapped by "If/Else/While" opcodes were supported.
2. The supported MLC code blocks were executed after loading the table
rather than being executed right in place.
============================================================
The demo of this order issue is as follows:
Name (OBJ1, 1)
If (CND1 == 1)
{
Name (OBJ2, 2)
}
Name (OBJ3, 3)
The original MLC support created OBJ2 after OBJ3's creation.
============================================================
Other than these limitations, MLC support in ACPICA looks correct. And
supporting this should be easy/natural for ACPICA, but enabling of this was
blocked by some ACPICA internal and OSPM specific initialization order
issues we've fixed recently. The wrong support started from the following
false bug fixing commit:
Commit: 80d7951177315f70b5ffd8663985fbf725d07799
Subject: Add support for module-level executable AML code.
We can confirm Windows interpreter behavior via reverse engineering means.
It can be proven that not only If/Else/While wrapped code blocks, all
opcodes can be executed at the module level, including operation region
accesses. And it can be proven that the MLC should be executed right in
place, not in such a deferred way executed after loading the table.
And the above facts indeed reflect the spec words around ACPI definition
block tables (DSDT/SSDT/...), the entire table and the Scope object is
defined by the AML specification in BNF style as:
AMLCode := DefBlockHeader TermList
DefScope := ScopeOp PkgLength NameString TermList
The bodies of the scope opening terms (AMLCode/Scope) are all TermList,
thus the table loading should be no difference than the control method
evaluations as the body of the Method is also defined by the AML
specification as TermList:
DefMethod := MethodOp PkgLength NameString MethodFlags TermList
The only difference is: after evaluating control method, created named
objects may be freed due to no reference, while named objects created by
the table loading should only be freed after unloading the table.
So this patch follows the spec and the de-facto standard behavior, enables
the new grammar (TermList) for the table loading.
By doing so, beyond the fixes to the above issues, we can see additional
differences comparing to the old grammar based table loading:
1. Originally, beyond the scope opening terms (AMLCode/Scope),
If/Else/While wrapped code blocks under the scope creating terms
(Device/PowerResource/Processor/ThermalZone) are also supported as
deferred MLC, which violates the spec defined grammar where ObjectList
is enforced. With MLC support improved as non-deferred, the interpreter
parses such scope creating terms as TermList rather ObjectList like the
scope opening terms.
After probing the Windows behavior and proving that it also parses these
terms as TermList, we submitted an ECR (Engineering Change Request) to
the ASWG (ACPI Specification Working Group) to clarify this. The ECR is
titled as "ASL Grammar Clarification for Executable AML Opcodes" and has
been accepted by the ASWG. The new grammar will appear in ACPI
specification 6.2.
2. Originally, Buffer/Package/OperationRegion/CreateXXXField/BankField
arguments are evaluated in a deferred way after loading the table. With
MLC support improved, they are also parsed right in place during the
table loading.
This is also Windows compliant and the only difference is the removal
of the debugging messages implemented before AcpiDsExecuteArguments(),
see Link 1 for the details. A previous commit should have ensured that
AcpiCheckAddressRange() won't regress.
Note that enabling this feature may cause regressions due to long term
Linux ACPI support on top of the wrong grammar. So this patch also prepares
a global option to be used to roll back to the old grammar during the
period between a regression is reported and the regression is
root-cause-fixed. Lv Zheng.
Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=112911
Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Originally, when AcpiGbl_Use32BitFadtAddresses is TRUE, GAS override can
only happen when the Address field mismatches.
According to the investigation result, Windows may favor 32-bit FADT
addresses in some cases. So we need this quirk working after enabling full
GAS support. This requires us to override GAS AccessSize/BitWidth/BitOffset
fields as long as AcpiGbl_Use32BitFadtAddresses is TRUE.
This patch enhances this quirk mechanism to make it working with full GAS
support. Lv Zheng.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=151501
Reported-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
This patch adds 2 new table events to indicate table
installation/uninstallation.
Currently, as ACPICA never uninstalls tables, this patch thus only add
table handler invocation for the table installation event. Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
AcpiTbInstallFixedTable() is now redundant as we've removed the fixed
table indexing mechanism. This patch cleans up the code accordingly.
No functional change. Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Consolidate multiple versions of strtoul64 to one common version.
limit possible bases to either 10 or 16.
Handles both implicit and explicit conversions.
Added a 2-character ascii-to-hex function for GPEs and buffers.
Adds a new file, utsrttoul64.c
Implement functions to read from or write to the PCI configuration space on the
efi environment.
The implementation expects that the number of bits (Width) to be 8, 16, 32 or 64.
Add also an auxiliar function that looks for the PCI device handler correspondent
to an ACPI_PCI_ID.
Signed-off-by: Marcelo Ferreira <joaomarcelo@lesc.ufc.br>
Add ACPI_EFI_PCI_IO protocol definition with the APIs needed by
AcpiOs{Read,Write}PciConfiguration on efi headers.
Signed-off-by: Marcelo Ferreira <joaomarcelo@lesc.ufc.br>
In MSVC9:
hwgpe.c(544) : warning C4244: 'function' : conversion from 'UIN32' to 'UINT8', possible loss of data
This patch fixes this issue. Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Fix 'logical-op' warning generated by gcc 6.0 or above regarding conditionals
as "if (File == stdout || File == stderr)" since in that environment both
stdout and stderr were expanded to ST->ConOut.
This patch replace the stdout and stderr defines by global variables to avoid
that issue.
Signed-off-by: Marcelo Ferreira <joaomarcelo@lesc.ufc.br>
There is a GCC false-warning issue on specific GCC versions that
"strchr" will be preprocessed and extracted to contain
!__buildin_constant_p() checker and it surely is a constant logical
value "1" for strchr() arguments. Then -Wlogical-op errorneously reports a
warning.
The regression is triggered after the standard headers are re-ordered in
the EFI porting task. This patch fixes this regression by moving the
workaround to a new position after including all other standard headers.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Originally compiler specific headers are included by the host-specific
headers. This makes build configuration management very inconvenient. And
many inclusion order issues can be hidden accross different host OSes. It
will then likely that some host builds will be broken just because of
fixing some inclusion order issues for other host builds.
This patch splits the compiler-specific header inclusions out of the
host-specific headers so that compiler-specific inclusion order issues will
not get entangled in the host-specific inclusion orders.
Note that intel compiler defines __GNUC__, so this patch contains special
handling because acintel.h and acgcc.h should be mutual exclusive.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>