Perform EC read and write via SystemIO when EmbeddedControl is unavailable. Not properly tested yet.
Re-sync against coreboot port. Does not yet handle SMM traps. In-progress. Cc: Sai Chaganty <rangasai.v.chaga...@intel.com> Cc: Isaac Oram <isaac.w.o...@intel.com> Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> Cc: Chasel Chiu <chasel.c...@intel.com> Signed-off-by: Benjamin Doron <benjamin.doro...@gmail.com> --- .../Acpi/BoardAcpiTables.inf | 4 + .../AspireVn7Dash572G/Acpi/BoardSsdt.asl | 29 +++- .../AspireVn7Dash572G/Acpi/battery.asl | 11 +- .../AspireVn7Dash572G/Acpi/ec.asl | 130 ++++++++-------- .../AspireVn7Dash572G/Acpi/eclib.asl | 141 ++++++++++++++++++ .../AspireVn7Dash572G/Acpi/mainboard.asl | 6 +- .../AspireVn7Dash572G/Acpi/thermal.asl | 16 +- 7 files changed, 256 insertions(+), 81 deletions(-) create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/eclib.asl diff --git a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/BoardAcpiTables.inf b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/BoardAcpiTables.inf index 806c0d2575c8..9a31b400a35e 100644 --- a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/BoardAcpiTables.inf +++ b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/BoardAcpiTables.inf @@ -13,5 +13,9 @@ MODULE_TYPE = USER_DEFINED VERSION_STRING = 1.0 +[Packages] + KabylakeOpenBoardPkg/OpenBoardPkg.dec + MdePkg/MdePkg.dec + [Sources] BoardSsdt.asl diff --git a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/BoardSsdt.asl b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/BoardSsdt.asl index cdec0434883e..d1609131ecf7 100644 --- a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/BoardSsdt.asl +++ b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/BoardSsdt.asl @@ -6,17 +6,44 @@ **/ +#include <IndustryStandard/Acpi63.h> + DefinitionBlock ( "Board.aml", "SSDT", - 0x02, + EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION, "ACRSKL", "AcerSKL ", 0x20141018 ) { + External (SSMP, IntObj) + External (SMIF, IntObj) External (\MDBG, MethodObj) + // SW SMI data port + OperationRegion (DPRT, SystemIO, 0xB3, 1) + Field (DPRT, ByteAcc, Lock, Preserve) + { + SSDP, 8 + } + + Name (ESMI, 0xDD) // TODO: Patch at runtime + Method (TRPS, 3, Serialized) + { + \DBGH (Concatenate ("SMIF: ", ToHexString (Arg0))) + \DBGH (Concatenate ("Param0: ", ToHexString (Arg1))) + \DBGH (Concatenate ("Param1: ", ToHexString (Arg2))) + + Local0 = Arg1 + Local0 |= (Arg2 << 4) + \DBGH (Concatenate ("Local0: ", ToHexString (Local0))) + + SMIF = Arg0 + SSDP = Local0 + SSMP = ESMI + } + // Debug print helper Method (DBGH, 1) { diff --git a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/battery.asl b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/battery.asl index 5ae4bdca89d5..1bf652c4a01e 100644 --- a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/battery.asl +++ b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/battery.asl @@ -184,11 +184,17 @@ Method (GBIF, 3, NotSerialized) Local7 = EBSN #endif Name (SERN, Buffer (0x06) { " " }) + /* Convert hex to decimal. + * - There appears to be a bug in the vendor's implementation: + * The correct answer has, or can have, 5 digits, so Local6 = 5. + * Also see "SERN" buffer. + * - Userspace prints reversed serial number? + */ Local6 = 4 While (Local7) { Divide (Local7, 10, Local5, Local7) - SERN[Local6] = (Local5 + 0x30) // Add ASCII 0x30 to get character + SERN[Local6] = (Local5 + 0x30) // Add 0x30 to get numeric character Local6-- } @@ -310,7 +316,7 @@ Method (GBST, 4, NotSerialized) // All on one page If (Arg2) { Local1 *= Local3 - Local1 /= 1000 /* Remainder ignored */ + Local1 /= 1000 /* Remainder ignored by vendor */ } } Else @@ -382,6 +388,7 @@ Device (BAT0) Method (_BIF, 0, NotSerialized) // _BIF: Battery Information { + /* Bitwise AND by vendor is lossy? */ Local6 = B0ST Local7 = 20 While (Local6 && Local7) diff --git a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/ec.asl b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/ec.asl index df71dd69b491..b8f0dba1597f 100644 --- a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/ec.asl +++ b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/ec.asl @@ -5,18 +5,33 @@ **/ -/* Global TODO: (externally: Optimus GC6 and GPS) +/* + * Global TODO: (externally: Optimus GC6 and GPS) * - TRPS: This is SMI 0xDD, likely in SmmOemDriver. This SW SMI adds to and executes * a table of function pointers produced throughout the OEM 'value-add' stack. + * - Arg0 - "SFUN" - is index into "$FNC" pointer table? It's easier to + * correlate *CommonService use: Offset 13 creates TRPS handlers. + * - Known functions: + * - 0x80 calls offset 0 in ACER_BOOT_DEVICE_SERVICE_PROTOCOL_GUID. + * - NB: efiXplorer can miss InstallProtocolInterface() when Interface is local + * - 0x81 toggles Intel Dynamic Acceleration in IA32_MISC_ENABLE MSR. + * - 0x82 does switch on "OSYS" to set EC byte. Suspect this is for OS features. + * (A CVE exists in the vendor code only if it never sets the offset in the buffer.) + * - RBEC/WBEC/MBEC: This is SMI 0xDD, "functions" 0x10, 0x11 and 0x12 in SmmKbcDriver, + * added into SmmCommonService table at its protocol notify. Performs read, write + * and read-modify-write from buffer. We will use ACPI instead. * - WMI: This is likely SMI 0xD0 in A01WMISmmCallback. This SW SMI likely uses the WMI * object and consumes the OEM 'value-add' stack for EC and presumably the A01* - * OEM/ODM 'value-add' stack. + * OEM/ODM 'value-add' stack. An SSDT contains the device and EC0 provides "GCMS" + * and "GOTS" method helpers. * - * Generally, more reversing is needed. + * Generally, more information is needed. + * TODO: Restore stripped features using reference code (except, check BoardAcpiDxe first) + * and implement more board features: lid and touchpad trigger wake from S3, + * Fn-Ctrl swap, sticky Fn keys and always-on USB charger. */ -/* TODO: Implement more features around reference code (except, check BoardAcpiDxe first) */ -// TODO: Enable and test +// TODO/TEST #undef LGMR_ENABLED // "DIDX" - "DeviceIdX" is uninitialised, cannot use "BRTN" method yet @@ -40,17 +55,7 @@ Device (\_SB.PCI0.LPCB.EC0) IO (Decode16, 0x66, 0x66, 0, 1) }) - OperationRegion (ECO1, SystemIO, 0x62, 1) - Field (ECO1, ByteAcc, Lock, Preserve) - { - PX62, 8 - } - - OperationRegion (ECO2, SystemIO, 0x66, 1) - Field (ECO2, ByteAcc, Lock, Preserve) - { - PX66, 8 - } + #include "eclib.asl" #ifdef LGMR_ENABLED OperationRegion (ECMB, SystemMemory, LGMR, 0x200) @@ -84,10 +89,12 @@ Device (\_SB.PCI0.LPCB.EC0) EX3G, 1, /* 3G */ , 3, RFEX, 1, /* RF present */ -#if 0 // Merely a guess - Offset (0x55), - BTH0, 8, /* Battery threshold? TODO: Actually diff in modified vendor FW */ -#endif +/* + * NOTE: Some reverse engineering, as well as corroborating vendor's hidden SetupUtility + * options with the EC's memory space, suggests that offset 0x55 might be the battery + * threshold + * - TODO: Actually diff changes in modified vendor FW + */ Offset (0x57), , 7, AHKB, 1, /* Hotkey triggered */ @@ -204,14 +211,19 @@ Device (\_SB.PCI0.LPCB.EC0) { TINI () EOSS = 0x05 -// OSIN () + // OSYS retrieved by SMM, Arg3 is unused +// TRPS (0x82, 1, 0) - /* Other pages return valid data too, but this seems to be the page + /* + * Other pages return valid data too, but this seems to be the page * we are expecting - persistently in ectool dump with vendor firmware - * FIXME: Contents of other pages? */ + * FIXME: Contents of other pages? + */ ETID = 0x20 } } + + /* iGFX RC method call stripped */ } Method (TINI, 0, NotSerialized) @@ -223,10 +235,8 @@ Device (\_SB.PCI0.LPCB.EC0) } Else { - /* WBEC: Called SMI function 0x11 */ -// EC_WRITE (0x92, 0) // ETAF = 0 - /* MBEC: Called SMI function 0x12 */ -// MBEC (0x10, 0xFD, 0x02) // ETEE = 1 + WBEC (0x92, 0) // ETAF = 0 + MBEC (0x10, 0xFD, 0x02) // ETEE = 1 } } @@ -234,10 +244,8 @@ Device (\_SB.PCI0.LPCB.EC0) Method (ECPS, 1, NotSerialized) // _PTS: Prepare To Sleep { ECSS = Arg0 -// COSI = OSYS -// SPR1 = Arg0 - /* TRPS: Generic SMI trap handler */ -// TRPS (0x82, 0x02) + // OSYS retrieved by SMM +// TRPS (0x82, 0x02, Arg0) If ((Arg0 == 3) || (Arg0 == 4)) { RFST = RFEX @@ -250,38 +258,23 @@ Device (\_SB.PCI0.LPCB.EC0) EOSS = Arg0 TINI () Notify (BAT0, 0x81) // Information Change -// COSI = OSYS -// SPR1 = Arg0 - /* TRPS: Generic SMI trap handler */ -// TRPS (0x82, 0x03) + // OSYS retrieved by SMM +// TRPS (0x82, 0x03, Arg0) If ((Arg0 == 3) || (Arg0 == 4)) { RFEX = RFST Notify (SLPB, 0x02) // Device Wake } + /* iGFX RC method call stripped */ } -#if 0 // TODO: Figure out what this is for - Method (OSIN, 0, NotSerialized) + Method (MBEC, 3, Serialized) { - COSI = OSYS - /* TRPS: Generic SMI trap handler */ - TRPS (0x82, 1) - } -#endif - -#if 0 // TODO: Implement - Method (MBEC, 3, Serialized) // Read-Modify-Write - { - /* Based on similar methods/tables at - * https://github.com/linuxhw/ACPI/blob/master/Notebook/Sony/SVE1713/SVE1713S1RW/506CDC50E671#L9359 - * which use ASL instead of SMM calls */ - Local0 = EC_READ (Arg0) + Local0 = RBEC (Arg0) Local0 &= Arg1 Local0 |= Arg2 - EC_WRITE (Arg0, Local0) + WBEC (Arg0, Local0) } -#endif /* Graphical hotkey */ Method (_Q19, 0, NotSerialized) @@ -316,7 +309,8 @@ Device (\_SB.PCI0.LPCB.EC0) } ElseIf ((Local1 > 0x80) && (Local1 < 0xA0)) { - TPEN ^= 1 /* TODO: Not working. What else does WMI do here? */ + /* TODO: Not working when called by HID mode. What does WMI do here? */ + TPEN ^= 1 } } } @@ -330,8 +324,7 @@ Device (\_SB.PCI0.LPCB.EC0) } Else { - /* MBEC: Called SMI function 0x12 */ -// MBEC (0x92, 0xF7, 0x08) // EOSD = 1 + MBEC (0x92, 0xF7, 0x08) // EOSD = 1 } Sleep (500) @@ -341,9 +334,8 @@ Device (\_SB.PCI0.LPCB.EC0) Method (_Q3F, 0, NotSerialized) { - \DBGH ("EC Query: 0x3F - TRPS") - /* TRPS: Generic SMI trap handler */ -// TRPS (0x80, 0) + // Arg3 is unused +// TRPS (0x80, 0, 0) } Method (_Q40, 0, NotSerialized) @@ -397,46 +389,44 @@ Device (\_SB.PCI0.LPCB.EC0) Method (_Q60, 0, NotSerialized) { - \DBGH ("EC Query: 0x60 -> WMI") + \DBGH ("EC Query (0x60): WMI") } Method (_Q61, 0, NotSerialized) { - \DBGH ("EC Query: 0x61 -> WMI") + \DBGH ("EC Query (0x61): WMI") } Method (_Q62, 0, NotSerialized) { - \DBGH ("EC Query: 0x62 -> Optimus GC6") + \DBGH ("EC Query (0x62): Optimus GC6 or NVIDIA GPS") } Method (_Q63, 0, NotSerialized) { - \DBGH ("EC Query: 0x63 -> Optimus GC6") + \DBGH ("EC Query (0x63): Optimus GC6 or NVIDIA GPS") } Method (_Q67, 0, NotSerialized) { - \DBGH ("EC Query: 0x67 -> NVIDIA GPS") + \DBGH ("EC Query (0x67): NVIDIA GPS") } Method (_Q68, 0, NotSerialized) { - \DBGH ("EC Query: 0x68 -> NVIDIA GPS") + \DBGH ("EC Query (0x68): NVIDIA GPS") } Method (_Q6C, 0, NotSerialized) { - \DBGH ("EC Query: 0x6C - TRPS") - /* TRPS: Generic SMI trap handler */ -// TRPS (0x81, 0) + // Arg3 is unused +// TRPS (0x81, 0, 0) } Method (_Q6D, 0, NotSerialized) { - \DBGH ("EC Query: 0x6D - TRPS") - /* TRPS: Generic SMI trap handler */ -// TRPS (0x81, 1) + // Arg3 is unused +// TRPS (0x81, 1, 0) } #include "ac.asl" diff --git a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/eclib.asl b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/eclib.asl new file mode 100644 index 000000000000..57921eb09c8b --- /dev/null +++ b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/eclib.asl @@ -0,0 +1,141 @@ +/** @file + This file contains the EC library for ACPI. + + Copyright (c) 2021, Baruch Binyamin Doron + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <EcCommands.h> + +Mutex (EMTX, 0) + +OperationRegion (ECO1, SystemIO, EC_D_PORT, 1) +Field (ECO1, ByteAcc, Lock, Preserve) +{ + ECDT, 8 +} + +OperationRegion (ECO2, SystemIO, EC_C_PORT, 1) +Field (ECO2, ByteAcc, Lock, Preserve) +{ + ECSC, 8 +} + +// Send EC command +// Return time elapsed on success, EC_TIME_OUT on failure +Method (SECC, 1, Serialized) +{ + // Wait EC timeout for input buffer to be empty + Local0 = 0 + While ((ECSC & EC_S_IBF) && Local0 < EC_TIME_OUT) + { + Stall (1) + Local0++ + } + // Send command if timeout was not reached + If (Local0 < EC_TIME_OUT) + { + ECSC = Arg0 + } + + // Return status + Return (Local0) +} + +// Send EC data +// Return time elapsed on success, EC_TIME_OUT on failure +Method (SECD, 1, Serialized) +{ + // Wait EC timeout for input buffer to be empty + Local0 = 0 + While ((ECSC & EC_S_IBF) && Local0 < EC_TIME_OUT) + { + Stall (1) + Local0++ + } + // Send data if timeout was not reached + If (Local0 < EC_TIME_OUT) + { + ECDT = Arg0 + } + + // Return status + Return (Local0) +} + +// Receive EC data +// Return data on success, EC_TIME_OUT on failure +Method (RECD, 0, Serialized) +{ + // Wait EC timeout for input buffer to be empty + Local0 = 0 + While ((ECSC & EC_S_OBF) && Local0 < EC_TIME_OUT) + { + Stall (1) + Local0++ + } + // Return data + If (Local0 < EC_TIME_OUT) + { + Return (ECDT) + } + + // Timeout exceeded, return failure + Return (Local0) +} + +// Read EC byte +// Return data on success, EC_TIME_OUT on failure +Method (RBEC, 1, Serialized) +{ + // Check for mutex acquired to not run with another function + Local0 = Acquire (EMTX, 0xFFFF) + If (Local0 == 0) + { + Local0 = SECC (EC_C_ACPI_READ) + } + + If (Local0 < EC_TIME_OUT) + { + // Send address + Local0 = SECD (Arg0) + } + + If (Local0 < EC_TIME_OUT) + { + // Receive data + Local0 = RECD () + } + + Release (EMTX) + Return (Local0) +} + +// Write EC byte +// Return time elapsed on success, EC_TIME_OUT on failure +Method (WBEC, 2, Serialized) +{ + // Check for mutex acquired to not run with another function + Local0 = Acquire (EMTX, 0xFFFF) + If (Local0 == 0) + { + Local0 = SECC (EC_C_ACPI_READ) + } + + If (Local0 < EC_TIME_OUT) + { + // Send address + Local0 = SECD (Arg0) + } + + If (Local0 < EC_TIME_OUT) + { + // Send data + Local0 = SECD (Arg1) + } + + Release (EMTX) + // Return data + Return (Local0) +} diff --git a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/mainboard.asl b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/mainboard.asl index 7a73d37429d0..46edce92fb47 100644 --- a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/mainboard.asl +++ b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/mainboard.asl @@ -6,25 +6,27 @@ **/ // TODO: Add HID support for touchpad, etc. +// - Does board actually support DPTF? #include "thermal.asl" External (\_SB.SLPB, DeviceObj) -// TODO: Need hooks from BoardAcpiDxe - Scope (_SB) { Method (MPTS, 1, NotSerialized) // _PTS: Prepare To Sleep { ^PCI0.LPCB.EC0.ECPS (Arg0) + /* TBT and DTS not supported, TPM.PTS can be called elsewhere */ } Method (MWAK, 1, Serialized) // _WAK: Wake { ^PCI0.LPCB.EC0.ECWK (Arg0) + /* No GPIO expander, 8254 clock-gating and PCIe PME can be performed elsewhere */ If ((Arg0 == 3) || (Arg0 == 4)) { + /* DTS and TBT not supported, iGFX RC variable update stripped */ Notify (LID0, 0x80) // Status Change } } diff --git a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/thermal.asl b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/thermal.asl index 805ee0700cd0..5d6604b41a9f 100644 --- a/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/thermal.asl +++ b/Platform/Intel/KabylakeOpenBoardPkg/AspireVn7Dash572G/Acpi/thermal.asl @@ -15,12 +15,16 @@ Scope (_TZ) { #ifdef LGMR_ENABLED Local0 = \_SB.PCI0.LPCB.EC0.MS0T -// Local1 = \_SB.PCI0.LPCB.EC0.MCSS + Local1 = \_SB.PCI0.LPCB.EC0.MCSS + /* Suppress warning over reading status flag by dummy OR */ + Or (Local1, 1, Local1) Local2 = \_SB.PCI0.LPCB.EC0.MOSD #else Local0 = \_SB.PCI0.LPCB.EC0.ES0T -// Local1 = \_SB.PCI0.LPCB.EC0.ESSF // "MCSS": Considering neighbouring bits, likely - // "ESSF" in thermals, not "ECSS" in notify + /* "MCSS": Considering neighbouring bits, likely + * "ESSF" in thermals, not "ECSS" in power notifications */ + Local1 = \_SB.PCI0.LPCB.EC0.ESSF + Or (Local1, 1, Local1) Local2 = \_SB.PCI0.LPCB.EC0.EOSD #endif If (Local2) // Thermal trip @@ -59,7 +63,7 @@ Scope (_TZ) Else { /* MBEC: Called SMI function 0x12 */ -// \_SB.PCI0.LPCB.EC0.MBEC (0x90, 0xFE, Arg0) // SCPM = Arg0 + \_SB.PCI0.LPCB.EC0.MBEC (0x90, 0xFE, Arg0) // SCPM = Arg0 } } @@ -89,6 +93,7 @@ Scope (_TZ) #else Local0 = \_SB.PCI0.LPCB.EC0.ES1T #endif + Return (C2K (Local0)) } @@ -116,7 +121,6 @@ Scope (_TZ) Local0 = 30 } - Local0 = ((Local0 * 10) + 2732) // Celsius to Kelvin - Return (Local0) + Return ((Local0 * 10) + 2732) // Celsius to centi-Kelvin } } -- 2.37.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#93288): https://edk2.groups.io/g/devel/message/93288 Mute This Topic: https://groups.io/mt/93507098/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-