diff --git a/bookshelf/Shelf 1 Getting Started/qemu/src/mu-tianocore-build.md b/bookshelf/Shelf 1 Getting Started/qemu/src/mu-tianocore-build.md
index 8cce809..f464e02 100644
--- a/bookshelf/Shelf 1 Getting Started/qemu/src/mu-tianocore-build.md
+++ b/bookshelf/Shelf 1 Getting Started/qemu/src/mu-tianocore-build.md
@@ -21,6 +21,7 @@ sudo apt-get install mono-complete
sudo apt-get install mtools
rustup override set nightly
cargo install cargo-make
+cargo install cargo-binutils
export GCC5_AARCH64_PREFIX=/usr/bin/aarch64-linux-gnu-
stuart_setup -c Platforms/QemuSbsaPkg/PlatformBuild.py TOOL_CHAIN_TAG=GCC5
stuart_update -c Platforms/QemuSbsaPkg/PlatformBuild.py TOOL_CHAIN_TAG=GCC5
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/book.toml b/bookshelf/Shelf 3 Specifications/EC Interface/book.toml
new file mode 100644
index 0000000..24a6ca4
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/book.toml
@@ -0,0 +1,2 @@
+[book]
+title = "EC Interface Specification"
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/README.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/README.md
new file mode 100644
index 0000000..80fc146
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/README.md
@@ -0,0 +1,11 @@
+# Embedded Controller Interface Specification
+
+Embedded Controller(EC) Interface Specification describes base set of requirements to interface to core windows features.
+It covers the following areas:
+- Firmware Management
+- Battery
+- Time and Alarm
+- UCSI
+- Thermal and Power
+- Input Devices
+- Customization
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/SUMMARY.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/SUMMARY.md
new file mode 100644
index 0000000..99b5dd9
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/SUMMARY.md
@@ -0,0 +1,31 @@
+# Summary
+
+[Introduction](README.md)
+
+[EC SOC Interface](ec-soc-interface.md)
+
+[Legacy EC Interface](legacy-ec-interface.md)
+
+[Secure EC Services Overview](secure-ec-services-overview.md)
+
+[EC Firmware Management](ec-firmware-management.md)
+
+[EC Power Service](ec-power-service.md)
+
+[Battery Service](battery-service.md)
+
+[Thermal Service](thermal-service.md)
+
+[UCSI Interface](ucsi-interface.md)
+
+[EC Input Management](ec-input-management.md)
+
+[EC Time Alarm Service](ec-time-alarm-service.md)
+
+[EC Debug Service](ec-debug-service.md)
+
+[EC Manufacturing Service](ec-manufacturing-service.md)
+
+[EC OEM Service](ec-oem-service.md)
+
+[Sample System Implementation](sample-system-implementation.md)
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/battery-service.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/battery-service.md
new file mode 100644
index 0000000..9417327
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/battery-service.md
@@ -0,0 +1,733 @@
+# Battery Service
+
+Battery control is monitored through the Modern Power Thermal Framework
+(MPTF). See this specification for further details on implementing
+firmware for these features. This section outlines the interface
+required in ACPI for this framework to function.
+
+| Command | Description |
+| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
+| EC_BAT_GET_BIX = 0x1 | Returns information about battery, model, serial number voltage. Note this is a superset of BIF. (MPTF) |
+| EC_BAT_GET_BST = 0x2 | Get Battery Status, must also have notify event on state change. (MPTF) |
+| EC_BAT_GET_PSR = 0x3 | Returns whether this power source device is currently online. (MPTF) |
+| EC_BAT_GET_PIF = 0x4 | Returns static information about a power source. (MPTF) |
+| EC_BAT_GET_BPS = 0x5 | Power delivery capabilities of battery at present time. (MPTF) |
+| EC_BAT_SET_BTP = 0x6 | Set battery trip point to generate SCI event (MPTF) |
+| EC_BAT_SET_BPT = 0x7 | Set Battery Power Threshold (MPTF) |
+| EC_BAT_GET_BPC = 0x8 | Returns static variables that are associated with system power characteristics on the battery path and power threshold support settings. (MPTF) |
+| EC_BAT_SET_BMC= 0x9 | Battery Maintenance Control |
+| EC_BAT_GET_BMD = 0xA | Returns battery information regarding charging and calibration |
+| EC_BAT_GET_BCT = 0xB | Returns battery charge time. |
+| EC_BAT_GET_BTM = 0xC | Get estimated runtime of battery while discharging |
+| EC_BAT_SET_BMS = 0xD | Sets battery capacity sampling time in ms |
+| EC_BAT_SET_BMA = 0xE | Battery Measurement Average Interval |
+| EC_BAT_GET_STA = 0xF | Get battery availability |
+
+## EC_BAT_GET_BIX
+
+Returns information about battery, model, serial number voltage etc
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bix-battery-information-extended)
+
+### FFA ACPI Example
+```
+Method (_BIX) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(144){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,1088,BIXD) // Out – Raw data response max length
+
+ Store(20, LENG)
+ Store(0x1, CMDD) // EC_BAT_GET_BIX
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BIXD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_GET_BST
+
+This object returns the present battery status. Whenever the Battery
+State value changes, the system will generate an SCI to notify the OS.
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bst-battery-status)
+
+### FFA ACPI Example
+
+```
+Method (_BST) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(34){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,128,BSTD) // Out – Raw data response 4 DWords
+
+ Store(20, LENG)
+ Store(0x2, CMDD) // EC_BAT_GET_BST
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BSTD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_GET_PSR
+
+Returns whether the power source device is currently in use. This can be
+used to determine if system is running off this power supply or adapter.
+On mobile systes this will report that the system is not running on the
+AC adapter if any of the batteries in the system is being forced to
+discharge. In systems that contains multiple power sources, this object
+reports the power source’s online or offline status.
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#battery-control-methods)
+
+### FFA ACPI Example
+
+```
+Method (_PSR) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(22){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,32,PSRD) // Out – Raw data response (overlaps with CMDD)
+
+ Store(20, LENG)
+ Store(0x3, CMDD) // EC_BAT_GET_PSR
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (PSRD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+## EC_BAT_GET_PIF
+
+This object returns information about the Power Source, which remains
+constant until the Power Source is changed. When the power source
+changes, the platform issues a Notify(0x0) (Bus Check) to the Power
+Source device to indicate that OSPM must re-evaluate the _PIF object.
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#pif-power-source-information)
+
+### FFA ACPI Example
+```
+Method (_PIF) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(22){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,1088,PIFD) // Out – Raw data response (overlaps with CMDD)
+ Store(20, LENG)
+ Store(0x4, CMDD) // EC_BAT_GET_PIF
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (PIFD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_GET_BPS
+
+This optional object returns the power delivery capabilities of the
+battery at the present time. If multiple batteries are present within
+the system, the sum of peak power levels from each battery can be used
+to determine the total available power.
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+
+```
+Method (_BPS) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(22){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,136,BPSD) // Out – BSP structure 5 integers
+
+ Store(20, LENG)
+ Store(0x5, CMDD) // EC_BAT_GET_BPS
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BPSD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_SET_BTP
+
+This object is used to set a trip point to generate an SCI whenever the
+Battery Remaining Capacity reaches or crosses the value specified in the
+_BTP object. Required on systems supporting Modern Standby
+
+[Platform design for modern standby | Microsoft
+Learn](https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/platform-design-for-modern-standby)
+
+### Input Parameters
+
+See ACPI documentation for details
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#btp-battery-trip-point)
+
+### Output Parameters
+
+None
+
+### FFA ACPI Example
+```
+Method (_BTP) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(24){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDWordField(BUFF,19, BTP1) // In – Battery Trip Point
+
+ Store(20, LENG)
+ Store(0x6, CMDD) // EC_BAT_SET_BTP
+ Store(Arg0, BTP1)
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (One)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_GET_BPC
+
+This optional object returns static values that are used to configure
+power threshold support in the platform firmware. OSPM can use the
+information to determine the capabilities of power delivery and
+threshold support for each battery in the system.
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bpc-battery-power-characteristics)
+
+### FFA ACPI Example
+```
+Method (_BPC) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(24){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,19,128, BPCD) // Out – BPC output Data
+
+ Store(20, LENG)
+ Store(0x8, CMDD) // EC_BAT_GET_BPC
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BPCD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+## EC_BAT_SET_BPT
+
+his optional object may be present under a battery device. OSPM must
+read _BPC first to determine the power delivery capability threshold
+support in the platform firmware and invoke this Method in order to
+program the threshold accordingly. If the platform does not support
+battery peak power thresholds, this Method should not be included in the
+namespace.
+
+### Input Parameters
+
+See ACPI specification for input parameters
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bpt-battery-power-threshold)
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bpt-battery-power-threshold)
+
+### FFA ACPI Example
+```
+Method (_BPT) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDwordField(BUFF,19, BPT1) // In – Averaging Interval
+ CreateDwordField(BUFF,23, BPT2) // In – Threshold ID
+ CreateDwordField(BUFF,27, BPT3) // In – Threshold Value
+ CreateField(BUFF,144,32,BPTD) // Out – BPT integer output
+
+ Store(0x30, LENG)
+ Store(0x7, CMDD) // EC_BAT_SET_BPT
+ Store(Arg0,BPT1)
+ Store(Arg1,BPT2)
+ Store(Arg2,BPT3)
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BPTD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_SET_BMC
+
+This object is used to initiate calibration cycles or to control the
+charger and whether or not a battery is powering the system. This object
+is only present under a battery device if the _BMD Capabilities Flags
+field has bit 0, 1, 2, or 5 set.
+
+### Input Parameters
+
+See ACPI specification for input parameter definition
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bmc-battery-maintenance-control)
+
+### Output Parameters
+
+None
+
+### FFA ACPI Example
+
+```
+Method (_BMC) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(22){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDWordField(BUFF,19, BMCF) // In – Feature Control Flags
+
+ Store(20, LENG)
+ Store(0x9, CMDD) // EC_BAT_SET_BMC
+ Store(Arg0,BMCF)
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (One)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_GET_BMD
+
+This optional object returns information about the battery’s
+capabilities and current state in relation to battery calibration and
+charger control features. If the _BMC object (defined below) is present
+under a battery device, this object must also be present. Whenever the
+Status Flags value changes, AML code will issue a
+Notify(battery_device, 0x82). In addition, AML will issue a
+Notify(battery_device, 0x82) if evaluating _BMC did not result in
+causing the Status Flags to be set as indicated in that argument to
+_BMC. AML is not required to issue Notify(battery_device, 0x82) if the
+Status Flags change while evaluating _BMC unless the change does not
+correspond to the argument passed to _BMC.
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bmd-battery-maintenance-data)
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+```
+Method (_BMD) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(40){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,160,BMDD) // Out – BMD structure 5 DWords
+
+ Store(20, LENG)
+ Store(0xA, CMDD) // EC_BAT_GET_BMD
+ Store(Arg0,BMCF)
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BMDD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+## EC_BAT_GET_BCT
+
+When the battery is charging, this optional object returns the estimated
+time from present to when it is charged to a given percentage of Last
+Full Charge Capacity.
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bct-battery-charge-time)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+```
+Method (_BCT) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(22){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDWordField(BUFF,19, CHLV) // In – ChargeLevel
+ CreateField(BUFF,144,32,BCTD) // Out – Raw data response (overlaps with CMDD)
+
+ Store(20, LENG)
+ Store(0xB, CMDD) // EC_BAT_GET_BCT
+ Store(Arg0,CHLV)
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BCTD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_GET_BTM
+
+This optional object returns the estimated runtime of the battery while
+it is discharging.
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#btm-battery-time)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+## EC_BAT_SET_BMS
+
+This object is used to set the sampling time of the battery capacity
+measurement, in milliseconds.
+
+The Sampling Time is the duration between two consecutive measurements
+of the battery’s capacities specified in _BST, such as present rate and
+remaining capacity. If the OSPM makes two succeeding readings through
+_BST beyond the duration, two different results will be returned.
+
+The OSPM may read the Max Sampling Time and Min Sampling Time with _BIX
+during boot time, and set a specific sampling time within the range with
+_BMS.
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bms-battery-measurement-sampling-time)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+
+```
+Method (_BMS) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDwordField(BUFF,19, BMS1) // In – Sampling Time
+ CreateField(BUFF,144,32,BMSD) // Out – BPT integer output
+
+ Store(20, LENG)
+ Store(0xD, CMDD) // EC_BAT_SET_BMS
+ Store(Arg0,BMS1)
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BMSD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_SET_BMA
+
+This object is used to set the averaging interval of the battery
+capacity measurement, in milliseconds. The Battery Measurement Averaging
+Interval is the length of time within which the battery averages the
+capacity measurements specified in _BST, such as remaining capacity and
+present rate.
+
+The OSPM may read the Max Average Interval and Min Average Interval with
+_BIX during boot time, and set a specific average interval within the
+range with _BMA.
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#bma-battery-measurement-averaging-interval)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+```
+Method (_BMA) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDwordField(BUFF,19, BMA1) // In – Averaging Interval
+ CreateField(BUFF,144,32,BMAD) // Out – BMA integer output
+
+ Store(20, LENG)
+ Store(0xE, CMDD) // EC_BAT_SET_BMA
+ Store(Arg0,BMS1)
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BMAD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_BAT_GET_STA
+
+Returns battery status to the OS along with any error conditions as defined by ACPI specification.
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+[10. Power Source and Power Meter Devices — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/06_Device_Configuration/Device_Configuration.html#sta-device-status)
+
+### FFA ACPI Example
+```
+Method (_STA) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(144){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,32,STAD) // Out – Raw data with status
+
+ Store(20, LENG)
+ Store(0xF, CMDD) // EC_BAT_GET_STA
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (STAD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-debug-service.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-debug-service.md
new file mode 100644
index 0000000..4f823b8
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-debug-service.md
@@ -0,0 +1,100 @@
+# EC Debug Service
+
+The debug service is used for telemetry, debug logs, system reset
+information etc.
+
+## Recovery Mode
+
+Put EC into recovery mode for development flashing and debugging.
+
+## Dump Debug State
+
+EC should be able to support typical engineering requests, such as
+getting detailed subsystem information, setting/getting GPIOs, etc, for
+design verification and benchtop testing.
+
+## Telemetry
+
+Ability to communicate with the HLOS event logging system, and record EC
+critical events for later analysis.
+
+## System Boot State
+
+In many designs, OEMs will desire indication that the system is
+responding to a power on request. This could be a logo display on the
+screen or a bezel LED. EC should be able to control these devices during
+the boot sequence.
+
+During first boot sequence EC may also be initialized and setup its
+services. Needs to know when OS is up to send notification for events
+that are only used by OS.
+
+## Memory Mapped Transactions
+
+There are two cases where you may want to use the memory mapped
+transactions. The first is if you have a large buffer you need to
+transfer data between EC and HLOS like a debug buffer. The second use
+case is if you want to emulate an eSPI memory mapped interface for
+compatibility with legacy devices.
+
+For this mode to work you will need memory carved out which is dedicated
+and shared between HLOS and secure world. In your UEFI memory map this
+memory should be marked as EfiMemoryReservedType so that the OS will not
+use or allocate the memory. In your SP manifest file you will also need
+to add access to this physical memory range. It needs to be aligned on a
+4K boundary and a multiple of 4K. This memory region is carved out and
+must never be used for any other purpose. Since the memory is shared
+with HLOS there is also no security surrounding accesses to the memory.
+
+### Example Memory Mapped Interface
+
+```
+// Map 4K memory region
+OperationRegion(ABCD, SystemMemory, 0xFFFF0000, 0x1000)
+
+// Map fields in region if you want to access or set via ACPI
+Field(ABCD,AnyAcc,Lock,Preserve) {
+ VER,16, // Version
+ RES, 16, // Reserved
+ VAR1,32, // 32-bit variable1
+ VAR2,64, // 64-bit variable1
+ VAR3,128, // 128-bit variable1
+}
+
+// DSM Method to send sync event
+Method(_DSM,4,Serialized,0,UnknownObj, {BuffObj, IntObj,IntObj,PkgObj})
+{
+ // Compare passed in UUID to Supported UUID
+ If(LEqual(Arg0,ToUUID(“6f8398c2-7ca4-11e4-ad36-631042b5008f”)))
+ {
+ // Use FFA to send Notification event down to copy data to EC
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+
+ Name(BUFF, Buffer(144){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,1024,FIFD) // Out – Msg data
+
+ // Create Doorbell Event
+ Store(20, LENG)
+ Store(0x0, CMDD) // UCSI set doorbell
+ Store(ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), UUID)
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (Zero)
+ } else {
+ Return(One)
+ }
+ } // End AVAL
+ } // End UUID
+} // End DSM
+
+```
+
+Any updates from the EC come back through a notification event
+registered in the FFA for this particular service.
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-firmware-management.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-firmware-management.md
new file mode 100644
index 0000000..c156394
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-firmware-management.md
@@ -0,0 +1,246 @@
+# EC Firmware Management
+
+This service is to provide details about the security state, supported
+features, debug, firmware version and firmware update functionality.
+
+NIST SP 800-193 compliance requires failsafe update of primary and
+backup EC FW images. EC should run from primary partition while writing
+backup partitions and then change flag to indicate backup becomes
+primary and primary becomes backup.
+
+| Capability Command | Description |
+| ----------------------------- | ----------------------------------------------------------- |
+| EC_CAP_GET_FW_STATE = 0x1 | Return details of FW in EC, DICE, Secure Boot, Version, etc |
+| EC_CAP_GET_SVC_LIST = 0x2 | Get list of services/features that this EC supports |
+| EC_CAP_GET_BID = 0x3 | Read Board ID that is used customized behavior |
+| EC_CAP_TEST_NFY = 0x4 | Create test notification event |
+
+## Get Firmware State
+
+Returns start of the overall EC if DICE and secure boot was enabled,
+currently running firmware version, EC status like boot failures.
+
+### Secure Boot and DICE
+
+DICE is a specification from the Trusted Computing Group that allows the
+MCU to verify the signature of the code that it is executing, thereby
+establishing trust in the code. To do this, it has a primary bootloader
+program that reads the firmware on flash and using a key that is only
+accessible by the ROM bootloader, can verify the authenticity of the
+firmware.
+
+[Trusted Platform Architecture - Device Identity
+Composition Engine
+(trustedcomputinggroup.org)](https://trustedcomputinggroup.org/wp-content/uploads/Hardware-Requirements-for-Device-Identifier-Composition-Engine-r78_For-Publication.pdf)
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+
+
+
+
+
+
+| FWVersion |
+16 |
+Version of FW running on EC |
+
+
+| SecureState |
+8 |
+Bit mask representing the secure state of the device
+0 – DICE is enabled
+1 – Firmware is signed |
+
+
+| BootStatus |
+8 |
+Boot status and error codes
+0 = SUCCESS |
+
+
+
+
+### FFA ACPI Example
+
+```
+Method (TFWS) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,32,FWSD) // Out – Raw data response (overlaps with CMDD)
+
+ Store(ToUUID("330c1273-fde5-4757-9819-5b6539037502"), UUID) // Management
+ Store(20, LENG)
+ Store(0x1, CMDD) // EC_CAP_GET_FW_STATE
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (FWSD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## Get Features Supported
+
+Get a list of services/features supported by this EC. Several features
+like HID devices are optional and may not be present. OEM services may
+also be added to this list as additional features supported.
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+
+
+
+
+
+
+| DebugMask |
+16 |
+0 – Supports reset reason
+1 – Supports debug tracing |
+
+
+| BatteryMask |
+8 |
+0 – Battery 0 present
+1 – Battery 1 present
+… |
+
+
+| FanMask |
+8 |
+0 – FAN 0 present
+1 – FAN 1 present
+… |
+
+
+| ThermalMask |
+8 |
+0 – Skin TZ present |
+
+
+| HIDMask |
+8 |
+0 – HID0 present
+1 – HID1 present
+… |
+
+
+| KeyMask |
+16 |
+0 – Power key present
+1 – LID switch present
+2 – VolUp Key Present
+3 – VolDown Key Present
+4 – Camera Key Present |
+
+
+ |
+ |
+ |
+
+
+
+
+### FFA ACPI Example
+```
+Method(TFET, 0x0, Serialized) {
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(24){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateField(BUFF,144,48,FETD) // Output Data
+
+ Store(20, LENG)
+ Store(0x2, CMDD) // EC_CAP_GET_SVC_LIST
+ Store(ToUUID("330c1273-fde5-4757-9819-5b6539037502"), UUID)
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) {
+ Return (FETD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## Get Board ID
+
+EC is often used to read pins or details to determine the HW
+configuration based on GPIO’s or ADC values. This ID allows SW to change
+behavior depending on this HW version information.
+
+### Input Parameters
+
+None
+
+### Output Parameters
+
+| Field | Bits | Description |
+| ------- | ---- | -------------- |
+| BoardID | 64 | Vendor defined |
+
+### FFA ACPI Example
+```
+Method(TBID, 0x0, Serialized) {
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateDwordField(BUFF,18,BIDD) // Output Data
+ Store(20, LENG)
+ Store(0x3, CMDD) // EC_CAP_GET_BID
+ Store(ToUUID("330c1273-fde5-4757-9819-5b6539037502"), UUID)
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) {
+ Return (BIDD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## Firmware Update
+
+This should initiate update of a particular firmware in the backup
+partition to provide NIST SP 800-193 failsafe compliance. EC firmware
+update is planned to be handled through CFU. Further details are
+available in CFU specification.
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-input-management.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-input-management.md
new file mode 100644
index 0000000..7c9e8b0
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-input-management.md
@@ -0,0 +1,72 @@
+# EC Input Management
+
+An EC may have several input devices including LID, Power key, touch and
+keyboard. HID based devices requiring low latency input, are recommended
+to be connected directly through a non-secure BUS interface such as I2C
+or I3C for performance reasons.
+
+## LID State
+
+Monitor sensors that indicate lid state. If lid is opened, potentially
+boot the system. If lid is closed, potentially shut down or hibernate
+the system.
+
+| **ACPI** | **Description** |
+| -------- | --------------------------------------------- |
+| _LID | Get state of LID device for clamshell designs |
+
+### ACPI Example for LID notificiation
+
+Assuming that LID is managed by the EC during registration we register
+for Input Management service for a Virtual ID = 1
+
+```
+Method(_RNY, 0, Serialized) {
+ Return( Package() {
+ Package(0x2) {
+ ToUUID("e3168a99-4a57-4a2b-8c5e-11bcfec73406"),
+ Buffer() {0x1,0x0} // Register event 0x1 for LID
+ }
+ } )
+ }
+
+ Method(_NFY, 2, Serialized) {
+ // Arg0 == UUID
+ // Arg1 == Notify ID
+ If(LEqual(ToUUID("e3168a99-4a57-4a2b-8c5e-11bcfec73406"),Arg0)) {
+ Switch(Arg1) {
+ Case(1) {
+ Notify(\\_SB._LID,0x80)
+ }
+ }
+ }
+}
+```
+
+## System Wake Event
+
+Ability to wake the system from various external events. This is for
+more complicated events that aren’t a simple GPIO for LID/Power button
+that require EC monitoring.
+
+## HID descriptor Interface
+
+Communication with EC must have packet sent/received in HID format so
+the OS HIDClass driver can properly understand requests. At this time
+HID packets will go over HIDI2C but in future these HID packets could be
+included over a single interface.
+
+| **HID IOCTL** | **Description** |
+| ------------------------------------ | ---------------------------------------------------------------------- |
+| IOCTL_HID_GET_DEVICE_DESCRIPTOR | Retrieves the device's HID descriptor |
+| IOCTL_HID_GET_DEVICE_ATTRIBUTES | Retrieves a device's attributes in a HID_DEVICE_ATTRIBUTES structure |
+| IOCTL_HID_GET_REPORT_DESCRIPTOR | Obtains the report descriptor for the HID device |
+| IOCTL_HID_READ_REPORT | Returns a report from the device into a class driver-supplied buffer |
+| IOCTL_HID_WRITE_REPORT | Transmits a class driver-supplied report to the device |
+| IOCTL_HID_GET_FEATURE | Get capabilities of a feature from the device |
+| IOCTL_HID_SET_FEATURE | Set/Enable a specific feature on device |
+| IOCTL_HID_GET_INPUT_REPORT | Get input report from HID device if input device |
+| IOCTL_HID_SET_OUTPUT_REPORT | Send output HID report to device |
+| IOCTL_HID_GET_STRING | Get a specific string from device |
+| IOCTL_HID_GET_INDEXED_STRING | Get a string from device based on index |
+| IOCTL_HID_SEND_IDLE_NOTIFICATION | Notification to idle device into idle/sleep state |
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-manufacturing-service.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-manufacturing-service.md
new file mode 100644
index 0000000..280bb01
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-manufacturing-service.md
@@ -0,0 +1,18 @@
+# EC Manufacturing Service
+
+This service should contain all the functionality that is need to
+perform self test, validation of the EC and special manufacturing modes.
+This service should be disabled on retail devices or at least protected
+to prevent unwanted modes.
+
+## Self Test
+
+EC should perform self test and return results/details of test
+validation
+
+## Set Calibration Data
+
+Have ability to store factory calibrations and setup information into EC
+non-volatile memory. For instance keyboard language information, or
+thermistor calibration values.
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-oem-service.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-oem-service.md
new file mode 100644
index 0000000..1978ae0
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-oem-service.md
@@ -0,0 +1,6 @@
+# EC OEM Service
+
+Any OEM special custom features should be put in their own service
+sandbox to support OEM specific features. This will prevent definitions
+from colliding with other services.
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-power-service.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-power-service.md
new file mode 100644
index 0000000..1bf3d23
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-power-service.md
@@ -0,0 +1,9 @@
+# EC Power Service
+
+## System Power State
+
+OS calls in to notify EC or a change in system power state.
+
+Perform appropriate power sequencing for the SoC from low power states
+(S3, S4, S5) to S0, and from S0 to low power states
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-soc-interface.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-soc-interface.md
new file mode 100644
index 0000000..0e8c800
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-soc-interface.md
@@ -0,0 +1,22 @@
+# EC SOC Interface
+
+## EC Physical Interface
+
+The interface by which the EC is physically wired to the SOC may vary
+depending on what interfaces are supported by the Silicon Vendor, EC
+manufacturer and OEM. It is recommended that a simple and low latency
+protocol is chosen such as eSPI, I3C, UART, memory.
+
+## EC Software Interface
+
+There are several existing OS interfaces that exist today via ACPI and
+HID to manage thermal, battery, keyboard, touch etc. These existing
+structures need to keep working and any new interface must be created in
+such a way that it does not break existing interfaces. This document
+covers details on how to implement EC services in secure world and keep
+compatibility with non-secure EC OperationRegions. It is important to
+work towards a more robust solution that will handle routing, larger
+packets and security in a common way across OS’s and across SV
+architectures.
+
+
\ No newline at end of file
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-time-alarm-service.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-time-alarm-service.md
new file mode 100644
index 0000000..785c762
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec-time-alarm-service.md
@@ -0,0 +1,334 @@
+# EC Time Alarm Service
+
+The following sections define the operation and definition of the
+optional control method-based Time and Alarm device, which provides a
+hardware independent abstraction and a more robust alternative to the
+Real Time Clock (RTC)
+
+ACPI specification details are in version 6.5 Chapter 9.
+
+[9. ACPI-Defined Devices and Device-Specific Objects — ACPI
+Specification 6.5 documentation
+(uefi.org)](https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#time-and-alarm-device)
+
+| **Command** | **Description** |
+| ----------------------- | ------------------------------------------------- |
+| EC_TAS_GET_GCP = 0x1 | Get the capabilities of the time and alarm device |
+| EC_TAS_GET_GRT = 0x2 | Get the Real Time |
+| EC_TAS_SET_SRT = 0x3 | Set the Real Time |
+| EC_TAS_GET_GWS = 0x4 | Get Wake Status |
+| EC_TAS_SET_CWS = 0x5 | Clear Wake Status |
+| EC_TAS_SET_STV = 0x6 | Set Timer value for given timer |
+| EC_TAS_GET_TIV = 0x7 | Get Timer value remaining for given timer |
+
+## EC_TAS_GET_GCP
+
+This object is required and provides the OSPM with a bit mask of the
+device capabilities.
+
+[9. ACPI-Defined Devices and Device-Specific Objects — ACPI
+Specification 6.5
+documentation](https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#gcp-get-capability)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI
+```
+Method (_GCP) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,32,GCPD) // Out – 32-bit integer described above
+
+ Store(20, LENG)
+ Store(0x1, CMDD) // EC_TAS_GET_GCP
+ Store(ToUUID("23ea63ed-b593-46ea-b027-8924df88e92f"), UUID) // RTC
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (GCDD)
+ }
+ }
+ Return(Zero)
+}
+```
+
+## EC_TAS_GET_GRT
+
+This object is required if the capabilities bit 2 is set to 1. The OSPM
+can use this object to get time. The return value is a buffer containing
+the time information as described below.
+
+[9. ACPI-Defined Devices and Device-Specific Objects — ACPI
+Specification 6.5
+documentation](https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#grt-get-real-time)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+```
+Method (_GRT) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,128,GRTD) // Out – 128-bit output structure above
+
+ Store(20, LENG)
+ Store(0x2, CMDD) // EC_TAS_GET_GRT
+ Store(ToUUID("23ea63ed-b593-46ea-b027-8924df88e92f"), UUID) // RTC
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (GRTD)
+ }
+ }
+ Return(Zero)
+}
+```
+
+## EC_TAS_SET_SRT
+
+This object is required if the capabilities bit 2 is set to 1. The OSPM
+can use this object to set the time.
+
+[9. ACPI-Defined Devices and Device-Specific Objects — ACPI
+Specification 6.5
+documentation](https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#srt-set-real-time)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+```
+Method (_SRT) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(30){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,152,128,GRTD) // In – 128-bit output structure above
+
+ Store(20, LENG)
+ Store(0x3, CMDD) // EC_TAS_SET_SRT
+ Store(ToUUID("23ea63ed-b593-46ea-b027-8924df88e92f"), UUID) // RTC
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (One)
+ }
+ }
+ Return(Zero)}
+}
+```
+
+## EC_TAS_GET_GWS
+
+This object is required if the capabilities bit 0 is set to 1. It
+enables the OSPM to read the status of wake alarms
+
+[9. ACPI-Defined Devices and Device-Specific Objects — ACPI
+Specification 6.5
+documentation](https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#gws-get-wake-alarm-status)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+```
+Method (_GWS) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(30){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDwordField(BUFF,19, GWS1) // In – Dword for timer type AC/DC
+ CreateField(BUFF,144,32,GWSD) // Out – Dword timer state
+
+ Store(20, LENG)
+ Store(0x4, CMDD) // EC_TAS_GET_GWS
+ Store(ToUUID("23ea63ed-b593-46ea-b027-8924df88e92f"), UUID) // RTC
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (GWSD)
+ }
+ }
+ Return(Zero)
+}
+```
+## EC_TAS_SET_CWS
+
+This object is required if the capabilities bit 0 is set to 1. It
+enables the OSPM to clear the status of wake alarms
+
+[9. ACPI-Defined Devices and Device-Specific Objects — ACPI
+Specification 6.5
+documentation](https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#cws-clear-wake-alarm-status)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+
+```
+Method (_CWS) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(30){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDwordField(BUFF,19, GWS1) // In – Dword for timer type AC/DC
+ CreateField(BUFF,144,32,CWSD) // Out – Dword timer state
+
+ Store(20, LENG)
+ Store(0x5, CMDD) // EC_TAS_SET_CWS
+ Store(Arg0,GWS1)
+ Store(ToUUID("23ea63ed-b593-46ea-b027-8924df88e92f"), UUID) // RTC
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (CWSD)
+ }
+ }
+ Return(Zero)
+}
+```
+
+## EC_TAS_SET_STV
+
+This object is required if the capabilities bit 0 is set to 1. It sets
+the timer to the specified value.
+
+[9. ACPI-Defined Devices and Device-Specific Objects — ACPI
+Specification 6.5
+documentation](https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#stv-set-timer-value)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+```
+Method (_STV) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(30){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDwordField(BUFF,19, GWS1) // In – Dword for timer type AC/DC
+ CreateDwordField(BUFF,23, GWS2) // In – Dword Timer Value
+ CreateField(BUFF,144,32,STVD) // Out – Dword timer state
+
+ Store(20, LENG)
+ Store(0x6, CMDD) // EC_TAS_SET_STV
+ Store(Arg0,GWS1)
+ Store(Arg1,GWS2)
+ Store(ToUUID("23ea63ed-b593-46ea-b027-8924df88e92f"), UUID) // RTC
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (STVD)
+ }
+ }
+ Return(Zero)
+}
+```
+
+## EC_TAS_GET_TIV
+
+This object is required if the capabilities bit 0 is set to 1. It
+returns the remaining time of the specified timer before that expires.
+
+[9. ACPI-Defined Devices and Device-Specific Objects — ACPI
+Specification 6.5
+documentation](https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#tiv-timer-values)
+
+### Input Parameters
+
+Input parameters as described in ACPI specification.
+
+### Output Parameters
+
+Should return structure as defined by ACPI specification
+
+### FFA ACPI Example
+
+```
+Method (_TIV) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(30){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDwordField(BUFF,19, GWS1) // In – Dword for timer type AC/DC
+ CreateField(BUFF,144,32,TIVD) // Out – Dword timer state
+
+ Store(20, LENG)
+ Store(0x7, CMDD) // EC_TAS_GET_TIV
+ Store(Arg0,GWS1)
+ Store(ToUUID("23ea63ed-b593-46ea-b027-8924df88e92f"), UUID) // RTC
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (TIVD)
+ }
+ }
+ Return(Zero)
+}
+```
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ec_specification.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec_specification.md
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ec_specification.md
@@ -0,0 +1 @@
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/legacy-ec-interface.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/legacy-ec-interface.md
new file mode 100644
index 0000000..ba56fa4
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/legacy-ec-interface.md
@@ -0,0 +1,227 @@
+# Legacy EC Interface
+
+ACPI specification has a definition for an embedded controller, however
+this implementation is tied very closely to the eSPI bus and x86
+architecture.
+
+The following is an example of legacy EC interface definition from ACPI
+
+[11.7. Thermal Zone Examples — ACPI Specification 6.4
+documentation](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/11_Thermal_Management/thermal-zone-examples.html)
+
+```
+Scope(\\_SB.PCI0.ISA0) {
+ Device(EC0) {
+ Name(_HID, EISAID("PNP0C09")) // ID for this EC
+
+ // current resource description for this EC
+ Name(_CRS, ResourceTemplate() {
+ IO(Decode16,0x62,0x62,0,1)
+ IO(Decode16,0x66,0x66,0,1)
+ })
+
+ Name(_GPE, 0) // GPE index for this EC
+
+ // create EC's region and field for thermal support
+ OperationRegion(EC0, EmbeddedControl, 0, 0xFF)
+ Field(EC0, ByteAcc, Lock, Preserve) {
+ MODE, 1, // thermal policy (quiet/perform)
+ FAN, 1, // fan power (on/off)
+ , 6, // reserved
+ TMP, 16, // current temp
+ AC0, 16, // active cooling temp (fan high)
+ , 16, // reserved
+ PSV, 16, // passive cooling temp
+ HOT 16, // critical S4 temp
+ CRT, 16 // critical temp
+ }
+
+ // following is a method that OSPM will schedule after
+ // it receives an SCI and queries the EC to receive value 7
+ Method(_Q07) {
+ Notify (\\_SB.PCI0.ISA0.EC0.TZ0, 0x80)
+ } // end of Notify method
+
+ // fan cooling on/off - engaged at AC0 temp
+ PowerResource(PFAN, 0, 0) {
+ Method(_STA) { Return (\\_SB.PCI0.ISA0.EC0.FAN) } // check power state
+ Method(_ON) { Store (One, \\\\_SB.PCI0.ISA0.EC0.FAN) } // turn on fan
+ Method(_OFF) { Store ( Zero, \\\\_SB.PCI0.ISA0.EC0.FAN) }// turn off
+fan
+ }
+
+ // Create FAN device object
+ Device (FAN) {
+ // Device ID for the FAN
+ Name(_HID, EISAID("PNP0C0B"))
+ // list power resource for the fan
+ Name(_PR0, Package(){PFAN})
+ }
+
+ // create a thermal zone
+ ThermalZone (TZ0) {
+ Method(_TMP) { Return (\\_SB.PCI0.ISA0.EC0.TMP )} // get current temp
+ Method(_AC0) { Return (\\_SB.PCI0.ISA0.EC0.AC0) } // fan high temp
+ Name(_AL0, Package(){\\_SB.PCI0.ISA0.EC0.FAN}) // fan is act cool dev
+ Method(_PSV) { Return (\\_SB.PCI0.ISA0.EC0.PSV) } // passive cooling
+temp
+ Name(_PSL, Package (){\\_SB.CPU0}) // passive cooling devices
+ Method(_HOT) { Return (\\_SB.PCI0.ISA0.EC0.HOT) } // get critical S4
+temp
+ Method(_CRT) { Return (\\_SB.PCI0.ISA0.EC0.CRT) } // get critical temp
+ Method(_SCP, 1) { Store (Arg1, \\\\_SB.PCI0.ISA0.EC0.MODE) } // set
+cooling mode
+
+ Name(_TSP, 150) // passive sampling = 15 sec
+ Name(_TZP, 0) // polling not required
+ Name (_STR, Unicode ("System thermal zone"))
+ } // end of TZ0
+ } // end of ECO
+} // end of \\\\_SB.PCI0.ISA0 scope-
+```
+
+On platforms that do not support IO port access there is an option to
+define MMIO regions to simulate the IO port transactions.
+
+In the above example you can see that the operation region directly maps
+to features on the EC and you can change the EC behavior by writing to a
+byte in the region or reading the latest data from the EC.
+
+For a system with the EC connected via eSPI and that needs a simple
+non-secure interface to the EC the above mapping works very well and
+keeps the code simple. The eSPI protocol itself has details on port
+accesses and uses the peripheral channel to easily read/write memory
+mapped regions.
+
+As the EC features evolve there are several requirements that do no work
+well with this interface:
+
+ - Different buses such as I3C, SPI, UART target a packet
+ request/response rather than a memory mapped interface
+
+ - Protected or restricted access and validation of request/response
+
+ - Firmware update, large data driven requests that require larger data
+ response the 256-byte region is limited
+
+ - Discoverability of features available and OEM customizations
+
+ - Out of order completion of requests, concurrency, routing and
+ priority handling
+
+As we try to address these limitations and move to a more packet based
+protocol described in this document. The following section covers
+details on how to adopt existing operation region to new ACPI
+functionality.
+
+## Adopting EC Operation Region
+
+The new OS frameworks such as MPTF still use ACPI methods as primary
+interface. Instead of defining devices such as FAN or ThermalZone in the
+EC region you can simply define the EC region itself and then map all
+the other ACPI functions to operate on this region. This will allow you
+to maintain backwards compatibility with existing EC definitions.
+
+```
+Device(EC0) {
+ Name(_HID, EISAID("PNP0C09")) // ID for this EC
+ // current resource description for this EC
+ Name(_CRS, ResourceTemplate() {
+ IO(Decode16,0x62,0x62,0,1)
+ IO(Decode16,0x66,0x66,0,1)
+ })
+
+ // create EC's region and field for thermal support
+ OperationRegion(EC0, EmbeddedControl, 0, 0xFF)
+ Field(EC0, ByteAcc, Lock, Preserve) {
+ MODE, 1, // thermal policy (quiet/perform)
+ FAN, 1, // fan power (on/off)
+ , 6, // reserved
+ TMP, 16, // current temp
+ AC0, 16, // active cooling temp (fan high)
+ , 16, // reserved
+ PSV, 16, // passive cooling temp
+ HOT 16, // critical S4 temp
+ CRT, 16 // critical temp
+ }
+}
+
+Device(SKIN) {
+ Name(_HID, "MSFT000A") // New MPTF HID Temperature Device
+ Method(_TMP, 0x0, Serialized) {
+ Return( \\_SB.PCI0.ISA0.EC0.TMP)
+ }
+}
+```
+
+For more complicated functions that take a package some of the data may
+be constructed within ACPI and some of the data pulled from the
+OperationRegion. For example BIX for battery information may have a
+combination of static and dynamic data like this:
+
+```
+Method (_BIX) {
+ Name (BAT0, Package (0x12)
+ {
+ 0x01, // Revision
+ 0x02, // Power Unit
+ 0x03, // Design Capacity
+ \\_SB.PCI0.ISA0.EC0.BFCC, // Last Full Charge Capacity
+ 0x05, // Battery Technology
+ 0x06, // Design Voltage
+ 0x07, // Design capacity of Warning
+ 0x08, // Design Capacity of Low
+ \\_SB.PCI0.ISA0.EC0.BCYL, // Cycle Count
+ 0x0A, // Measurement Accuracy
+ 0x0B, // Max Sampling Time
+ 0x0C, // Min Sampling Time
+ 0x0D, // Max Averaging Interval
+ 0x0E, // Min Averaging Interval
+ 0x0F, // Battery Capacity Granularity 1
+ 0x10, // Battery Capacity Granularity 2
+ "Model123", // Model Number
+ "Serial456", // Serial Number
+ "Li-Ion", // Battery Type
+ "OEMName" // OEM Information
+ })
+ Return(BAT0)
+}
+```
+
+## Limitations for using Legacy EC
+
+Before using the Legacy EC definition OEM’s should be aware of several
+use cases that may limit you ability to use it.
+
+### ACPI support for eSPI master
+
+In the case of Legacy EC the communication to the EC is accomplished
+directly by the ACPI driver using PORT IO and eSPI Peripheral Bus
+commands. On ARM platforms there is no PORT IO and these must be
+substituted with MMIO regions. The ACPI driver needs changes to support
+MMIO which is being evaluated and support is not yet available. Some
+Silicon Vendors also do not implement the full eSPI specification and as
+such the ACPI driver cannot handle all the communication needs. On these
+platforms using Legacy EC interface is not an option.
+
+### Security of eSPI bus
+
+When non-secure world is given access to the eSPI bus it can send
+commands to device on that bus. Some HW designs have the TPM or SPINOR
+on the same physical bus as the EC. On these designs allowing non-secure
+world to directly sends commands to EC can break the security
+requirements of other devices on the bus. In these cases the eSPI
+communication must be done in the secure world over FF-A as covered in
+this document and not use the Legacy EC channel. Since non-secure world
+has complete access to the EC operation region there is no chance for
+encryption of data. All data in the operation region is considered
+non-secure.
+
+### Functional limitations of Legacy EC
+
+The peripheral region that is mapped in the Legacy EC in ACPI is limited
+to 256 bytes and notification events to the ones that are defined and
+handled in ACPI driver. To create custom solutions, send large packets
+or support encryption of data the Legacy EC interface has limitations in
+this area.
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image1.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image1.png
new file mode 100644
index 0000000..ddb8ed9
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image1.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image10.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image10.png
new file mode 100644
index 0000000..40166de
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image10.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image11.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image11.png
new file mode 100644
index 0000000..5e48059
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image11.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image12.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image12.png
new file mode 100644
index 0000000..d434bf2
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image12.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image13.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image13.png
new file mode 100644
index 0000000..fd8b30b
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image13.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image14.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image14.png
new file mode 100644
index 0000000..298e5e7
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image14.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image15.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image15.png
new file mode 100644
index 0000000..d2e2157
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image15.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image2.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image2.png
new file mode 100644
index 0000000..870c27c
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image2.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image3.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image3.png
new file mode 100644
index 0000000..7a3036d
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image3.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image4.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image4.png
new file mode 100644
index 0000000..e68bfe1
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image4.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image5.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image5.png
new file mode 100644
index 0000000..25232c4
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image5.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image6.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image6.png
new file mode 100644
index 0000000..5dc3519
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image6.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image7.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image7.png
new file mode 100644
index 0000000..5ae2d66
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image7.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image8.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image8.png
new file mode 100644
index 0000000..40c1aee
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/image8.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/media/odp_arch.png b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/odp_arch.png
new file mode 100644
index 0000000..9e65c04
Binary files /dev/null and b/bookshelf/Shelf 3 Specifications/EC Interface/src/media/odp_arch.png differ
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/sample-system-implementation.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/sample-system-implementation.md
new file mode 100644
index 0000000..e7c2c46
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/sample-system-implementation.md
@@ -0,0 +1,481 @@
+# Sample System Implementation
+
+## ACPI Interface Definition
+
+### FFA Device Definition
+
+```
+Device(\\_SB_.FFA0) {
+ Name(_HID, "MSFT000C")
+ OperationRegion(AFFH, FFixedHw, 4, 144)
+ Field(AFFH, BufferAcc, NoLock, Preserve) { AccessAs(BufferAcc, 0x1), FFAC, 1152 }
+
+ // Other components check this to make sure FFA is available
+ Method(AVAL, 0, Serialized) {
+ Return(One)
+ }
+
+ // Register notification events from FFA
+ Method(_RNY, 0, Serialized) {
+ Return( Package() {
+ Package(0x2) { // Events for Management Service
+ ToUUID("330c1273-fde5-4757-9819-5b6539037502"),
+ Buffer() {0x1,0x0} // Register event 0x1
+ },
+ Package(0x2) { // Events for Thermal service
+ ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"),
+ Buffer() {0x1,0x0,0x2,0x0,0x3,0x0} // Register events 0x1, 0x2, 0x3
+ },
+ Package(0x2) { // Events for input device
+ ToUUID("e3168a99-4a57-4a2b-8c5e-11bcfec73406"),
+ Buffer() {0x1,0x0} // Register event 0x1 for LID
+ }
+ } )
+ }
+
+ Method(_NFY, 2, Serialized) {
+ // Arg0 == UUID
+ // Arg1 == Notify ID
+ // Management Service Events
+
+ If(LEqual(ToUUID("330c1273-fde5-4757-9819-5b6539037502"),Arg0)) {
+ Switch(Arg1) {
+ Case(1) { // Test Notification Event
+ Notify(\\_SB.ECT0,0x20)
+ }
+ }
+ }
+
+ // Thermal service events
+ If(LEqual(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"),Arg0)) {
+ Switch(Arg1) {
+ Case(1) { // Temp crossed low threshold
+ Notify(\\_SB.SKIN,0x80)
+ }
+ Case(2) { // Temp crossed high threshold
+ Notify(\\_SB.SKIN,0x81)
+ }
+ Case(3) { // Critical temperature event
+ Notify(\\_SB.SKIN,0x82)
+ }
+ }
+ }
+
+ // Input Device Events
+ If(LEqual(ToUUID("e3168a99-4a57-4a2b-8c5e-11bcfec73406"),Arg0)) {
+ Switch(Arg1) {
+ Case(1) { // LID event
+ Notify(\\_SB._LID,0x80)
+ }
+ }
+ }
+ }
+}
+```
+
+### Memory Mapped Interface via FFA for UCSI
+
+Note for this implementation of memory mapped interface to work the
+memory must be marked as reserved by UEFI and not used by the OS and
+direct access also given to the corresponding service in secure world.
+
+```
+Device(USBC) {
+ Name(_HID,EISAID(“USBC000”))
+ Name(_CID,EISAID(“PNP0CA0”))
+ Name(_UID,1)
+ Name(_DDN, “USB Type-C”)
+ Name(_ADR,0x0)
+ OperationRegion(USBC, SystemMemory, UCSI_PHYS_MEM, 0x30)
+ Field(USBC,AnyAcc,Lock,Preserve)
+ {
+ // USB C Mailbox Interface
+ VERS,16, // PPM-\>OPM Version
+ RES, 16, // Reservied
+ CCI, 32, // PPM-\>OPM CCI Indicator
+ CTRL,64, // OPM-\>PPM Control Messages
+ MSGI,128, // OPM-\>PPM Message In
+ MSGO,128, // PPM-\>OPM Message Out
+ }
+
+ Method(_DSM,4,Serialized,0,UnknownObj, {BuffObj, IntObj,IntObj,PkgObj})
+ {
+
+ // Compare passed in UUID to Supported UUID
+ If(LEqual(Arg0,ToUUID(“6f8398c2-7ca4-11e4-ad36-631042b5008f”)))
+ {
+ // Use FFA to send Notification event down to copy data to EC
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(144){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,1024,FIFD) // Out – Msg data
+
+ // Create Doorbell Event
+ Store(20, LENG)
+ Store(0x0, CMDD) // UCSI set doorbell
+ Store(ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), UUID)
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+ } // End AVAL
+ } // End UUID
+ } // End DSM
+}
+```
+
+### Thermal ACPI Interface for FFA
+
+This sample code shows one Microsoft Thermal zone for SKIN and then a
+thermal device THRM for implementing customized IO.
+
+```
+// Sample Definition of FAN ACPI
+Device(SKIN) {
+ Name(_HID, "MSFT000A")
+
+ Method(_TMP, 0x0, Serialized) {
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(30){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateByteField(BUFF,19,TZID) // Temp Sensor ID
+ CreateDWordField(BUFF,26,RTMP) // Output Data
+
+ Store(20, LENG)
+ Store(0x1, CMDD) // EC_THM_GET_TMP
+ Store(0x2, TZID) // Temp zone ID for SKIIN
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID)
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (RTMP)
+ }
+ }
+ Return (Ones)
+ }
+
+ // Arg0 Temp sensor ID
+ // Arg1 Package with Low and High set points
+ Method(THRS,0x2, Serialized) {
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateByteField(BUFF,19,TZID) // Temp Sensor ID
+ CreateDwordField(BUFF,20,VTIM) // Timeout
+ CreateDwordField(BUFF,24,VLO) // Low Threshold
+ CreateDwordField(BUFF,28,VHI) // High Threshold
+ CreateDWordField(BUFF,18,TSTS) // Output Data
+
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID)
+ Store(32, LENG)
+ Store(0x2, CMDD) // EC_THM_SET_THRS
+ Store(Arg0, TZID)
+ Store(DeRefOf(Index(Arg1,0)),VTIM)
+ Store(DeRefOf(Index(Arg1,1)),VLO)
+ Store(DeRefOf(Index(Arg1,2)),VHI)
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (TSTS)
+ }
+ }
+ Return (0x3) // Hardware failure
+ }
+
+ // Arg0 GUID 1f0849fc-a845-4fcf-865c-4101bf8e8d79
+ // Arg1 Revision
+ // Arg2 Function Index
+ // Arg3 Function dependent
+ Method(_DSM, 0x4, Serialized) {
+ If(LEqual(ToUuid("1f0849fc-a845-4fcf-865c-4101bf8e8d79"),Arg0)) {
+ Switch(Arg2) {
+ Case (0) {
+ Return(0x3) // Support Function 0 and Function 1
+ }
+ Case (1) {
+ Return( THRS(0x2, Arg3) ) // Call to function to set threshold
+ }
+ }
+ }
+ Return(0x3)
+ }
+}
+
+Device(THRM) {
+ Name(_HID, "MSFT000B")
+
+ // Arg0 Instance ID
+ // Arg1 UUID of variable
+ // Return (Status,Value)
+ Method(GVAR,2,Serialized) {
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(38){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateByteField(BUFF,19,INST) // Instance ID
+ CreateWordField(BUFF,20,VLEN) // 16-bit variable length
+ CreateField(BUFF,176,128,VUID) // UUID of variable to read
+ CreateField(BUFF,208,64,RVAL) // Output Data
+
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID)
+ Store(38, LENG)
+ Store(0x5, CMDD) // EC_THM_GET_VAR
+ Store(Arg0,INST) // Save instance ID
+ Store(4,VLEN) // Variable is always DWORD here
+ Store(Arg1, VUID)
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (RVAL)
+ }
+ }
+ Return (0x3)
+ }
+
+ // Arg0 Instance ID
+ // Arg1 UUID of variable
+ // Return (Status,Value)
+ Method(SVAR,3,Serialized) {
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(42){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateByteField(BUFF,19,INST) // Instance ID
+ CreateWordField(BUFF,20,VLEN) // 16-bit variable length
+ CreateField(BUFF,176,128,VUID) // UUID of variable to read
+ CreateDwordField(BUFF,38,DVAL) // Data value
+ CreateField(BUFF,208,32,RVAL) // Ouput Data
+
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID)
+ Store(42, LENG)
+ Store(0x6, CMDD) // EC_THM_SET_VAR
+ Store(Arg0,INST) // Save instance ID
+ Store(4,VLEN) // Variable is always DWORD here
+ Store(Arg1, VUID)
+ Store(Arg2,DVAL)
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (RVAL)
+ }
+ }
+ Return (0x3)
+ }
+
+ // Arg0 GUID
+ // 07ff6382-e29a-47c9-ac87-e79dad71dd82 - Input
+ // d9b9b7f3-2a3e-4064-8841-cb13d317669e - Output
+ // Arg1 Revision
+ // Arg2 Function Index
+ // Arg3 Function dependent
+ Method(_DSM, 0x4, Serialized) {
+ // Input Variable
+ If(LEqual(ToUuid("07ff6382-e29a-47c9-ac87-e79dad71dd82"),Arg0)) {
+ Switch(Arg2) {
+ Case(0) {
+ // We support function 0-3
+ Return(0xf)
+ }
+ Case(1) {
+ Return(GVAR(1,ToUuid("ba17b567-c368-48d5-bc6f-a312a41583c1"))) // OnTemp
+ }
+ Case(2) {
+ Return(GVAR(1,ToUuid("3a62688c-d95b-4d2d-bacc-90d7a5816bcd"))) // RampTemp
+ }
+ Case(3) {
+ Return(GVAR(1,ToUuid("dcb758b1-f0fd-4ec7-b2c0-ef1e2a547b76"))) // MaxTemp
+ }
+ }
+ Return(0x1)
+ }
+
+ // Output Variable
+ If(LEqual(ToUuid("d9b9b7f3-2a3e-4064-8841-cb13d317669e"),Arg0)) {
+ Switch(Arg2) {
+ Case(0) {
+ // We support function 0-3
+ Return(0xf)
+ }
+ Case(1) {
+ Return(SVAR(1,ToUuid("ba17b567-c368-48d5-bc6f-a312a41583c1"),Arg3)) // OnTemp
+ }
+ Case(2) {
+ Return(SVAR(1,ToUuid("3a62688c-d95b-4d2d-bacc-90d7a5816bcd"),Arg3)) // RampTemp
+ }
+ Case(3) {
+ Return(SVAR(1,ToUuid("dcb758b1-f0fd-4ec7-b2c0-ef1e2a547b76"),Arg3)) // MaxTemp
+ }
+ }
+ }
+ Return (0x1)
+ }
+}
+```
+
+## Call Flows for secure and non-secure Implementation
+
+Depending on system requirements the ACPI calls may go directly to the
+EC or through secure world then through to EC.
+
+When using non-secure interface the ACPI functions must define protocol
+level which is the Embedded controller for eSPI. For I2C/I3C or SPI
+interfaces the corresponding ACPI device must define the bus dependency
+and build the packet directly that is sent to the EC.
+
+For secure communication all data is sent to the secure world via FF-A
+commands described in this document and the actual bus protocol and data
+sent to the EC is defined in the secure world in Hafnium. All support
+for FF-A is inboxed in the OS by default so EC communication will always
+work in any environment. However, FF-A is not supported in x86/x64
+platforms so direct EC communication must be used on these platforms.
+
+### Non-Secure eSPI Access
+
+This call flow assumes using Embedded controller definition with
+independent ACPI functions for MPTF support
+
+#### Non-Secure eSPI READ
+
+```
+Device(EC0) {
+ Name(_HID, EISAID("PNP0C09")) // ID for this EC
+
+ // current resource description for this EC
+ Name(_CRS, ResourceTemplate() {
+ Memory32Fixed (ReadWrite, 0x100000, 0x10) // Used for simulated port access
+ Memory32Fixed (ReadWrite, 0x100010, 0x10)
+ // Interrupt defined for eSPI event signalling
+ GpioInt(Edge, ActiveHigh, ExclusiveAndWake,PullUp 0,"\\_SB.GPI2"){43}
+ })
+
+ Name(_GPE, 0) // GPE index for this EC
+
+ // create EC's region and field for thermal support
+ OperationRegion(EC0, EmbeddedControl, 0, 0xFF)
+ Field(EC0, ByteAcc, Lock, Preserve) {
+ MODE, 1, // thermal policy (quiet/perform)
+ FAN, 1, // fan power (on/off)
+ , 6, // reserved
+ TMP, 16, // current temp
+ AC0, 16, // active cooling temp (fan high)
+ , 16, // reserved
+ PSV, 16, // passive cooling temp
+ HOT 16, // critical S4 temp
+ CRT, 16 // critical temp
+ BST1, 32, // Battery State
+ BST2, 32, // Battery Present Rate
+ BST3, 32, // Battery Remaining capacity
+ BST4, 32, // Battery Present Voltage
+ }
+
+ Method (_BST) {
+ Name (BSTD, Package (0x4)
+ {
+ \\_SB.PCI0.ISA0.EC0.BST1, // Battery State
+ \\_SB.PCI0.ISA0.EC0.BST2, // Battery Present Rate
+ \\_SB.PCI0.ISA0.EC0.BST3, // Battery Remaining Capacity
+ \\_SB.PCI0.ISA0.EC0.BST4, // Battery Present Voltage
+ })
+ Return(BSTD)
+ }
+}
+```
+
+
+
+#### Non-Secure eSPI Notifications
+
+All interrupts are handled by the ACPI driver. When EC needs to send a
+notification event the GPIO is asserted and traps into IRQ. ACPI driver
+reads the EC_SC status register to determine if an SCI is pending. DPC
+callback calls and reads the EC_DATA port to determine the _Qxx event
+that is pending. Based on the event that is determined by ACPI the
+corresponding _Qxx event function is called.
+
+```
+Method (_Q07) {
+ // Take action for event 7
+ Notify(\\_SB._LID, 0x80)
+}
+```
+
+
+
+### Secure eSPI Access
+
+The following flow assumes ARM platform using FF-A for secure calls.
+Note if you want to use the same EC firmware on both platforms with
+secure and non-secure access the EC_BAT_GET_BST in this case should
+be convert to a peripheral access with the same IO port and offset as
+non-secure definition.
+
+#### Secure eSPI READ
+```
+Method (_BST) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateDwordField(BUFF,19, BMA1) // In – Averaging Interval
+ CreateField(BUFF,144,128,BSTD) // Out – 4 DWord BST data
+
+ Store(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID) // Battery
+ Store(42, LENG)
+ Store(0x6, CMDD) // EC_BAT_GET_BST
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (BMAD)
+ }
+ }
+ Return(Zero)
+}
+```
+
+
+
+#### Secure eSPI Notification
+
+When EC communication is done through Secure world we assert FIQ which
+is handled as eSPI interrupt. eSPI driver reads EC_SC and EC_DATA to
+retrieve the notification event details. On Non-secure implementation
+ACPI converts this to Qxx callback. On secure platform this is converted
+to a virtual ID and sent back to the OS via _NFY callback and a virtual
+ID.
+
+```
+Method(_NFY, 2, Serialized) {
+ // Arg0 == UUID
+ // Arg1 == Notify ID
+ If(LEqual(ToUUID("25cb5207-ac36-427d-aaef-3aa78877d27e"),Arg0)) {
+ If(LEqual(0x2,Arg1)) {
+ Store(Arg1, \\_SB.ECT0.NEVT)
+ Notify(\\_SB._LID, 0x80)
+ }
+ }
+}
+```
+
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/secure-ec-services-overview.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/secure-ec-services-overview.md
new file mode 100644
index 0000000..7920965
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/secure-ec-services-overview.md
@@ -0,0 +1,913 @@
+# Secure EC Services Overview
+
+In this section we review a system design where the EC communication is
+in the secure world running in a dedicated SP. In a system without
+secure world or where communication to EC is not desired to be secure
+all the ACPI functions can be mapped directly to data from the EC
+operation region.
+
+The following github projects provide sample implementations of this interface:
+
+[ACPI EC samples, Kernel mode test driver, User mode test driver](https://github.com/opendevicepartnership/ec-test-app)
+[Sample Secure Partition Service for EC services in RUST](https://github.com/opendevicepartnership/haf-ec-service)
+[RUST crate for FFA implementation in secure partition](https://github.com/opendevicepartnership/ffa)
+
+The following GUID’s have been designed to represent each service
+operating in the secure partition for EC.
+
+
+
+
+
+
+| EC_SVC_MANAGEMENT |
+330c1273-fde5-4757-9819-5b6539037502 |
+Used to query EC functionality, Board info, version, security state, FW update |
+
+EC_SVC_POWER |
+7157addf-2fbe-4c63-ae95-efac16e3b01c |
+Handles general power related requests and OS Sx state transition state notification |
+
+EC_SVC_BATTERY |
+25cb5207-ac36-427d-aaef-3aa78877d27e |
+Handles battery info, status, charging |
+
+EC_SVC_THERMAL |
+31f56da7-593c-4d72-a4b3-8fc7171ac073 |
+Handles thermal requests for skin and other thermal events |
+
+EC_SVC_UCSI |
+65467f50-827f-4e4f-8770-dbf4c3f77f45 |
+Handles PD notifications and calls to UCSI interface |
+
+EC_SVC_INPUT |
+e3168a99-4a57-4a2b-8c5e-11bcfec73406 |
+Handles wake events, power key, lid, input devices (HID separate instance) |
+
+EC_SVC_TIME_ALARM |
+23ea63ed-b593-46ea-b027-8924df88e92f |
+Handles RTC and wake timers. |
+
+EC_SVC_DEBUG |
+0bd66c7c-a288-48a6-afc8-e2200c03eb62 |
+Used for telemetry, debug control, recovery modes, logs, etc |
+
+EC_SVC_TEST |
+6c44c879-d0bc-41d3-bef6-60432182dfe6 |
+Used to send commands for manufacturing/factory test |
+
+EC_SVC_OEM1 |
+9a8a1e88-a880-447c-830d-6d764e9172bb |
+Sample OEM custom service and example piping of events |
+
+
+
+
+## FFA Overview
+
+This section covers the components involved in sending a command to EC
+through the FFA flow in windows. This path is specific to ARM devices
+and a common solution with x64 is still being worked out. Those will
+continue through the non-secure OperationRegion in the near term.
+
+
+
+ARM has a standard for calling into the secure world through SMC’s and
+targeting a particular service running in secure world via a UUID. The
+full specification and details can be found here: [Firmware Framework
+for A-Profile](https://developer.arm.com/Architectures/Firmware%20Framework%20for%20A-Profile)
+
+The windows kernel provides native ability for ACPI to directly send and
+receive FFA commands. It also provides a driver ffadrv.sys to expose a
+DDI that allows other drivers to directly send/receive FFA commands
+without needing to go through ACPI.
+
+Hyper-V forwards the SMC’s through to EL3 to Hafnium which then uses the
+UUID to route the request to the correct SP and service. From the
+corresponding EC service it then calls into the eSPI or underlying
+transport layer to send and receive the request to the physical EC.
+
+### FFA Device Definition
+
+The FFA device is loaded from ACPI during boot and as such requires a
+Device entry in ACPI
+
+```
+ Name(_HID, "MSFT000C")
+
+ OperationRegion(AFFH, FFixedHw, 4, 144)
+ Field(AFFH, BufferAcc, NoLock, Preserve) { AccessAs(BufferAcc, 0x1), FFAC, 1152 }
+
+
+ Name(_DSD, Package() {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), //Device Prop UUID
+ Package() {
+ Package(2) {
+ "arm-arml0002-ffa-ntf-bind",
+ Package() {
+ 1, // Revision
+ 2, // Count of following packages
+ Package () {
+ ToUUID("330c1273-fde5-4757-9819-5b6539037502"), // Service1 UUID
+ Package () {
+ 0x01, //Cookie1 (UINT32)
+ 0x07, //Cookie2
+ }
+ },
+ Package () {
+ ToUUID("b510b3a3-59f6-4054-ba7a-ff2eb1eac765"), // Service2 UUID
+ Package () {
+ 0x01, //Cookie1
+ 0x03, //Cookie2
+ }
+ }
+ }
+ }
+ }
+ }) // _DSD()
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // Arg0 - UUID
+ // Arg1 - Revision
+ // Arg2: Function Index
+ // 0 - Query
+ // 1 - Notify
+ // 2 - binding failure
+ // 3 - infra failure
+ // Arg3 - Data
+
+ //
+ // Device specific method used to query
+ // configuration data. See ACPI 5.0 specification
+ // for further details.
+ //
+ If(LEqual(Arg0, Buffer(0x10) {
+ //
+ // UUID: {7681541E-8827-4239-8D9D-36BE7FE12542}
+ //
+ 0x1e, 0x54, 0x81, 0x76, 0x27, 0x88, 0x39, 0x42, 0x8d, 0x9d, 0x36, 0xbe, 0x7f, 0xe1, 0x25, 0x42
+ }))
+ {
+ // Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ Return(Buffer(One) { 0x03 }) // Bitmask Query + Notify
+ }
+
+ // Notify Function
+ If(LEqual(Arg2, One))
+ {
+ // Arg3 - Package {UUID, Cookie}
+ Store(Index(Arg3,1), \_SB.ECT0.NEVT )
+ Return(Zero)
+ }
+ } Else {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method(AVAL,0x0, Serialized)
+ {
+ Return(One)
+ }
+}
+```
+
+#### HID definition
+
+The _HID “MSFT000C” is reserved for FFA devices. Defining this HID for
+your device will cause the FFA interface for the OS to be loaded on this
+device.
+
+#### Operation Region Definition
+
+The operation region is marked as FFixedHw type 4 which lets the ACPI
+interpreter know that any read/write to this region requires special
+handling. The length is 144 bytes because this region operates on
+registers X0-X17 each of which are 8 bytes 18\*8 = 144 bytes. This is
+mapped to FFAC is 1152 bits (144\*8) and this field is where we act
+upon.
+
+```
+OperationRegion(AFFH, FFixedHw, 4, 144)
+Field(AFFH, BufferAcc, NoLock, Preserve) { AccessAs(BufferAcc, 0x1),FFAC, 1152 }
+```
+
+When reading and writing from this operation region the FFA driver does
+some underlying mapping for X0-X3
+
+```
+X0 = 0xc400008d // FFA_DIRECT_REQ2
+X1 = (Receiver Endpoint ID) | (Sender Endpoint ID \<\< 16)
+X2/X3 = UUID
+```
+
+The following is the format of the request and response packets that are
+sent via ACPI
+
+```
+FFA_REQ_PACKET
+{
+ uint8 status; // Not used just populated so commands are symmetric
+ uint8 length; // Number of bytes in rawdata
+ uint128 UUID;
+ uint8 reqdata[];
+}
+
+FFA_RSP_PACKET
+{
+ uint8 status; // Status from ACPI if FFA command was sent successfully
+ uint8 length;
+ uint128 UUID;
+ uint64 ffa_status; // Status returned from the service of the FFA command
+ uint8 rspdata[];
+}
+
+CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+CreateField(BUFF,16,128,UUID) // In/Out - UUID of service
+CreateDwordField(BUFF,18,FFST)// Out - FFA command status
+```
+
+#### Register Notification
+
+During FFA driver initialization it calls into secure world to get a
+list of all available services for each secure partition. After this we
+send a NOTIFICATION_REGISTRATION request to each SP that has a service
+which registers for notification events
+
+```
+ Name(_DSD, Package() {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), //Device Prop UUID
+ Package() {
+ Package(2) {
+ "arm-arml0002-ffa-ntf-bind",
+ Package() {
+ 1, // Revision
+ 1, // Count of following packages
+ Package () {
+ ToUUID("330c1273-fde5-4757-9819-5b6539037502"), // Service1 UUID
+ Package () {
+ 0x01, //Cookie1 (UINT32)
+ 0x07, //Cookie2
+ }
+ },
+ }
+ }
+ }
+ }) // _DSD()
+```
+
+
+
+In the above example we indicate that the OS will handle 2 different
+notification events for UUID 330c1273-fde5-4757-9819-5b6539037502 which
+is our EC management UUID. FFA knows which secure partition this maps to
+based on the list of services for each SP it has retrieved. Rather than
+having to keep track of all the physical bits in the bitmask that are
+used the FFA driver keeps track of this and allows each service to
+create a list of virtual ID’s they need to handle. The FFA driver then
+maps this to one of the available bits in the hardware bitmask and
+passes this mapping down to the notification service running in a given
+SP.
+
+Input
+
+
+
+
+
+| Function |
+X4 |
+0x1 |
+
+UUID Lo |
+X5 |
+Bytes [0..7] for the service UUID. |
+
+UUID Hi |
+X6 |
+Bytes [8..16] for the service UUID. |
+
+Mappings Count |
+X7 |
+The number of notification mappings |
+
+Notification Mapping1 |
+X8 |
+Bits [0..16] – Notification ID. --> 0,1,2,3,...
+
+Bits [16..32] – Notification Bitmap bit number (0-383). |
+
+Notification Mapping2 |
+X9 |
+Bits [0..16] – Notification ID. --> 0,1,2,3,...
+
+Bits [16..32] – Notification Bitmap bit number (0-383).
+ |
+
+... |
+... |
+... |
+
+
+
+
+
+
+Output
+
+| Parameter | Register | Value |
+| ---------- | --------- | -------------------------------- |
+| Result | X4 | 0 on success. Otherwise, Failure |
+
+
+
+Note this NOTIFICATION_REGISTER request is sent to the
+Notification Service UUID in the SP. The UUID of the service that the
+notifications are for are stored in X5/X6 registers shown above.
+
+The UUID for notification service is
+{B510B3A3-59F6-4054-BA7A-FF2EB1EAC765} which is stored in X2/X3.
+
+#### Notification Events
+
+All notification events sent from all secure partitions are passed back
+through the FFA driver. The notification calls the _DSM method. Function 0
+is always a bitmap of all the other functions supported. We must support at
+least a minium of the Query and Notify.
+The UUID is stored in Arg0 and the notification cookie is stored in Arg3 when Arg2 is 11.
+```
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // Arg0 - UUID
+ // Arg1 - Revision
+ // Arg2: Function Index
+ // 0 - Query
+ // 1 - Notify
+ // 2 - binding failure
+ // 3 - infra failure
+ // Arg3 - Data
+
+ //
+ // Device specific method used to query
+ // configuration data. See ACPI 5.0 specification
+ // for further details.
+ //
+ If(LEqual(Arg0, Buffer(0x10) {
+ //
+ // UUID: {7681541E-8827-4239-8D9D-36BE7FE12542}
+ //
+ 0x1e, 0x54, 0x81, 0x76, 0x27, 0x88, 0x39, 0x42, 0x8d, 0x9d, 0x36, 0xbe, 0x7f, 0xe1, 0x25, 0x42
+ }))
+ {
+ // Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ Return(Buffer(One) { 0x03 }) // Bitmask Query + Notify
+ }
+
+ // Notify Function
+ If(LEqual(Arg2, One))
+ {
+ // Arg3 - Package {UUID, Cookie}
+ Store(Index(Arg3,1), \_SB.ECT0.NEVT )
+ Return(Zero)
+ }
+ } Else {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+```
+
+The following is the call flow showing a secure interrupt arriving to
+the EC service which results in a notification back to ACPI. The
+notification payload can optionally be written to a shared buffer or
+ACPI can make another call back into EC service to retrieve the
+notification details.
+
+The _NFY only contains the ID of the notification and no other payload,
+so both ACPI and the EC service must be designed either with shared
+memory buffer or a further notify data packet.
+
+
+
+## Runtime Requests
+
+During runtime the non-secure side uses FFA_MSG_SEND_DIRECT_REQ2
+requests to send requests to a given service within an SP. Any request
+that is expected to take longer than 500 uSec should yield control back
+to the OS by calling FFA_YIELD within the service. When FFA_YIELD is
+called it will return control back to the OS to continue executing but
+the corresponding ACPI thread will be blocked until the original FFA
+request completes with DIRECT_RSP2. Note this creates a polling type
+interface where the OS will resume the SP thread after the timeout
+specified. The following is sample call sequence.
+
+
+
+### FFA Example Data Flow
+
+For an example let’s take the battery status request _BST and follow
+data through.
+
+
+
+```
+FFA_REQ_PACKET req = {
+ 0x0, // Initialize to no error
+ 0x1, // Only 1 byte of data is sent after the header
+ {0x25,0xcb,0x52,0x07,0xac,0x36,0x42,0x7d,0xaa,0xef,0x3a,0xa7,0x88,0x77,0xd2,0x7e},
+ 0x2 // EC_BAT_GET_BST
+}
+```
+
+The equivalent to write this data into a BUFF in ACPI is as follows
+
+```
+Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+CreateField(BUFF,16,128,UUID) // UUID of service
+CreateByteField(BUFF,18, CMDD) // In – First byte of command
+CreateField(BUFF,144,128,BSTD) // Out – Raw data response 4 DWords
+Store(20,LENG)
+Store(0x2, CMDD)
+Store(ToUUID ("25cb5207-ac36-427d-aaef-3aa78877d27e"), UUID)
+Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+```
+
+The ACPI interpreter when walking through this code creates a buffer and
+populates the data into buffer. The last line indicates to send this
+buffer over FFA interface.
+
+ACPI calls into the FFA interface to send the data over to the secure
+world EC Service
+
+```
+typedef struct _FFA_INTERFACE {
+ ULONG Version;
+ PFFA_MSG_SEND_DIRECT_REQ2 SendDirectReq2;
+} FFA_INTERFACE, \*PFFA_INTERFACE;
+````
+
+### FFA Parsing
+
+FFA is in charge of sending the SMC over to the secure world and routing
+to the correct service based on UUID.
+
+
+
+```
+X0 = SEND_DIRECT_REQ2 SMC command ID
+X1 = Source ID and Destination ID
+X2 = UUID Low
+X3 = UUID High
+X4-X17 = rawdata
+```
+
+**Note:** The status and length are not passed through to the secure
+world they are consumed only be ACPI.
+
+HyperV and Monitor have a chance to filter or deny the request, but in
+general just pass the SMC request through to Hafnium
+
+Hafnium extracts the data from the registers into an sp_msg structure
+which is directly mapping contents from x0-x17 into these fields.
+
+```
+pub struct FfaParams {
+ pub x0: u64,
+ pub x1: u64,
+ pub x2: u64,
+ pub x3: u64,
+ pub x4: u64,
+ pub x5: u64,
+ pub x6: u64,
+ pub x7: u64,
+ pub x8: u64,
+ pub x9: u64,
+ pub x10: u64,
+ pub x11: u64,
+ pub x12: u64,
+ pub x13: u64,
+ pub x14: u64,
+ pub x15: u64,
+ pub x16: u64,
+ pub x17: u64,
+}
+```
+
+In our SP we receive the raw FfaParams structure and we convert this to
+an FfaMsg using our translator. This pulls out the function_id,
+source_id, destination_id and uuid.
+
+```
+fn from(params: FfaParams) -> FfaMsg {
+ FfaMsg {
+ function_id: params.x0, // Function id is in lower 32 bits of x0
+ source_id: (params.x1 >> 16) as u16, // Source in upper 16 bits
+ destination_id: params.x1 as u16, // Destination in lower 16 bits
+ uuid: u64_to_uuid(params.x2, params.x3),
+ args64: [
+ params.x4, params.x5, params.x6, params.x7, params.x8, params.x9, params.x10,
+ params.x11, params.x12, params.x13, params.x14, params.x15, params.x16, params.x17,
+ ],
+ }
+}
+```
+
+The destination_id is used to route the message to the correct SP, this
+is based on the ID field in the DTS description file. Eg: id =
+<0x8001>;
+
+### EC Service Parsing
+
+Within the EC partition there are several services that run, the routing
+of the FF-A request to the correct services is done by the main message
+handling loop for the secure partition. After receiving a message we
+call into ffa_msg_handler and based on the UUID send it to the
+corresponding service to handle the message.
+
+```
+let mut next_msg = ffa.msg_wait();
+loop {
+ match next_msg {
+ Ok(ffamsg) => match ffa_msg_handler(&ffamsg) {
+ Ok(msg) => next_msg = ffa.msg_resp(\&msg),
+ Err(_e) => panic!("Failed to handle FFA msg"),
+ },
+ Err(_e) => {
+ panic!("Error executing msg_wait");
+ }
+ }
+}
+```
+
+The main message loop gets the response back from ffa_msg_handler and
+returns to non-secure world so the next incoming message after the
+response is a new message to handle.
+
+```
+fn ffa_msg_handler(msg: &FfaMsg) -> Result {
+ println!(
+ "Successfully received ffa msg:
+ function_id = {:08x}
+ uuid = {}",
+ msg.function_id, msg.uuid
+ );
+
+ match msg.uuid {
+ UUID_EC_SVC_MANAGEMENT => {
+ let fwmgmt = fw_mgmt::FwMgmt::new();
+ fwmgmt.exec(msg)
+ }
+
+ UUID_EC_SVC_NOTIFY => {
+ let ntfy = notify::Notify::new();
+ ntfy.exec(msg)
+ }
+
+ UUID_EC_SVC_POWER => {
+ let pwr = power::Power::new();
+ pwr.exec(msg)
+ }
+
+ UUID_EC_SVC_BATTERY => {
+ let batt = battery::Battery::new();
+ batt.exec(msg)
+ }
+
+ UUID_EC_SVC_THERMAL => {
+ let thm = thermal::ThmMgmt::new();
+ thm.exec(msg)
+ }
+
+ UUID_EC_SVC_UCSI => {
+ let ucsi = ucsi::UCSI::new();
+ ucsi.exec(msg)
+ }
+
+ UUID_EC_SVC_TIME_ALARM => {
+ let alrm = alarm::Alarm::new();
+ alrm.exec(msg)
+ }
+
+ UUID_EC_SVC_DEBUG => {
+ let dbg = debug::Debug::new();
+ dbg.exec(msg)
+ }
+
+ UUID_EC_SVC_OEM => {
+ let oem = oem::OEM::new();
+ oem.exec(msg)
+ }
+
+ _ => panic!("Unknown UUID"),
+ }
+}
+```
+
+### Large Data Transfers
+
+When making an FFA_MSG_SEND_DIRECT_REQ2 call the data is stored in
+registers X0-X17. X0-X3 are reserved to store the Function Id, Source
+Id, Destination Id and UUID. This leaves X4-X17 or 112 bytes. For larger
+messages they either need to be broken into multiple pieces or make use
+of a shared buffer between the OS and Secure Partition.
+
+#### Shared Buffer Definitions
+
+To create a shared buffer you need to modify the dts file for the secure
+partition to include mapping to your buffer.
+
+```
+ns_comm_buffer {
+ description = "ns-comm";
+ base-address = <0x00000100 0x60000000>;
+ pages-count = <0x8>;
+ attributes = ;
+};
+```
+
+During UEFI Platform initialization you will need to do the following
+steps, see the FFA specification for more details on these commands
+
+ - FFA_MAP_RXTX_BUFFER
+ - FFA_MEM_SHARE
+ - FFA_MSG_SEND_DIRECT_REQ2 (EC_CAP_MEM_SHARE)
+ - FFA_UNMAP_RXTX_BUFFER
+
+The RXTX buffer is used during larger packet transfers but can be
+overridden and updated by the framework. The MEM_SHARE command uses the
+RXTX buffer so we first map that buffer then populate our memory
+descriptor requests to the TX_BUFFER and send to Hafnium. After sending
+the MEM_SHARE request we need to instruct our SP to retrieve this
+memory mapping request. This is done through our customer
+EC_CAP_MEM_SHARE request where we describe the shared memory region
+that UEFI has donated. From there we call FFA_MEM_RETRIEVE_REQ to map
+the shared memory that was described to Hafnium. After we are done with
+the RXTX buffers we must unmap them as the OS will re-map new RXTX
+buffers. From this point on both Non-secure and Secure side will have
+access to this shared memory buffer that was allocated.
+
+### Async Transfers
+
+All services are single threaded by default. Even when doing FFA_YIELD
+it does not allow any new content to be executed within the service. If
+you need your service to be truly asynchronous you must have commands
+with delayed responses.
+
+There is no packet identifier by default and tracking of requests and
+completion by FFA, so the sample solution given here is based on shared
+buffers defined in previous section and existing ACPI and FFA
+functionality.
+
+
+
+Inside of our FFA functions rather than copying our data payload into
+the direct registers we define a queue in shared memory and populate the
+actual data into this queue entry. In the FFA_MSG_SEND_DIRECT_REQ2
+we populate an ASYNC command ID (0x0) along with the seq \#. The seq \#
+is then used by the service to locate the request in the TX queue. We
+define a separate queue for RX and TX so we don’t need to synchronize
+between OS and secure partition.
+
+
+
+### ACPI Structures and Methods for Asynchronous
+
+The SMTX is shared memory TX region definition
+
+```
+// Shared memory regions and ASYNC implementation
+OperationRegion (SMTX, SystemMemory, 0x10060000000, 0x1000)
+
+// Store our actual request to shared memory TX buffer
+Field (SMTX, AnyAcc, NoLock, Preserve)
+{
+ TVER, 16,
+ TCNT, 16,
+ TRS0, 32,
+ TB0, 64,
+ TB1, 64,
+ TB2, 64,
+ TB3, 64,
+ TB4, 64,
+ TB5, 64,
+ TB6, 64,
+ TB7, 64,
+ Offset(0x100), // First Entry starts at 256 byte offset each entry is 256 bytes
+ TE0, 2048,
+ TE1, 2048,
+ TE2, 2048,
+ TE3, 2048,
+ TE4, 2048,
+ TE5, 2048,
+ TE6, 2048,
+ TE7, 2048,
+}
+```
+
+The QTXB method copies data into first available entry in the TX queue
+and returns sequence number used.
+
+```
+// Arg0 is buffer pointer
+// Arg1 is length of Data
+// Return Seq \#
+Method(QTXB, 0x2, Serialized) {
+ Name(TBX, 0x0)
+ Store(Add(ShiftLeft(1,32),Add(ShiftLeft(Arg1,16),SEQN)),TBX)
+ Increment(SEQN)
+ // Loop until we find a free entry to populate
+ While(One) {
+ If(LEqual(And(TB0,0xFFFF),0x0)) {
+ Store(TBX,TB0); Store(Arg0,TE0); Return( And(TBX,0xFFFF) )
+ }
+
+ If(LEqual(And(TB1,0xFFFF),0x0)) {
+ Store(TBX,TB1); Store(Arg0,TE1); Return( And(TBX,0xFFFF) )
+ }
+
+ If(LEqual(And(TB2,0xFFFF),0x0)) {
+ Store(TBX,TB2); Store(Arg0,TE2); Return( And(TBX,0xFFFF) )
+ }
+
+ If(LEqual(And(TB3,0xFFFF),0x0)) {
+ Store(TBX,TB3); Store(Arg0,TE3); Return( And(TBX,0xFFFF) )
+ }
+
+ If(LEqual(And(TB4,0xFFFF),0x0)) {
+ Store(TBX,TB4); Store(Arg0,TE4); Return( And(TBX,0xFFFF) )
+ }
+
+ If(LEqual(And(TB5,0xFFFF),0x0)) {
+ Store(TBX,TB5); Store(Arg0,TE5); Return( And(TBX,0xFFFF) )
+ }
+
+ If(LEqual(And(TB6,0xFFFF),0x0)) {
+ Store(TBX,TB6); Store(Arg0,TE6); Return( And(TBX,0xFFFF) )
+ }
+
+ If(LEqual(And(TB7,0xFFFF),0x0)) {
+ Store(TBX,TB7); Store(Arg0,TE7); Return( And(TBX,0xFFFF) )
+ }
+
+ Sleep(5)
+ }
+}
+```
+
+The SMRX is shared memory region for RX queues
+
+```
+// Shared memory region
+OperationRegion (SMRX, SystemMemory, 0x10060001000, 0x1000)
+
+// Store our actual request to shared memory TX buffer
+Field (SMRX, AnyAcc, NoLock, Preserve)
+{
+ RVER, 16,
+ RCNT, 16,
+ RRS0, 32,
+ RB0, 64,
+ RB1, 64,
+ RB2, 64,
+ RB3, 64,
+ RB4, 64,
+ RB5, 64,
+ RB6, 64,
+ RB7, 64,
+ Offset(0x100), // First Entry starts at 256 byte offset each entry is 256 bytes
+ RE0, 2048,
+ RE1, 2048,
+ RE2, 2048,
+ RE3, 2048,
+ RE4, 2048,
+ RE5, 2048,
+ RE6, 2048,
+ RE7, 2048,
+}
+```
+
+The RXDB function takes sequence number as input and will keep looping
+through all the entries until we see packet has completed. Sleeps for
+5ms between each iteration to allow the OS to do other things and other
+ACPI threads can run.
+
+```
+// Allow multiple threads to wait for their SEQ packet at once
+// If supporting packet \> 256 bytes need to modify to stitch together packet
+Method(RXDB, 0x1, Serialized) {
+ Name(BUFF, Buffer(256){})
+ // Loop forever until we find our seq
+ While (One) {
+ If(LEqual(And(RB0,0xFFFF),Arg0)) {
+ CreateField(BUFF, 0, Multiply(And(ShiftRight(RB0,16),0xFFFF),8), XB0)
+ Store(RE0,BUFF); Store(0,RB0); Return( XB0 )
+ }
+
+ If(LEqual(And(RB1,0xFFFF),Arg0)) {
+ CreateField(BUFF, 0, Multiply(And(ShiftRight(RB1,16),0xFFFF),8), XB1)
+ Store(RE1,BUFF); Store(0,RB1); Return( XB1 )
+ }
+
+ If(LEqual(And(RB2,0xFFFF),Arg0)) {
+ CreateField(BUFF, 0, Multiply(And(ShiftRight(RB2,16),0xFFFF),8), XB2)
+ Store(RE2,BUFF); Store(0,RB2); Return( XB2 )
+ }
+
+ If(LEqual(And(RB3,0xFFFF),Arg0)) {
+ CreateField(BUFF, 0, Multiply(And(ShiftRight(RB3,16),0xFFFF),8), XB3)
+ Store(RE3,BUFF); Store(0,RB3); Return( XB3 )
+ }
+
+ If(LEqual(And(RB4,0xFFFF),Arg0)) {
+ CreateField(BUFF, 0, Multiply(And(ShiftRight(RB4,16),0xFFFF),8), XB4)
+ Store(RE4,BUFF); Store(0,RB4); Return( XB4 )
+ }
+
+ If(LEqual(And(RB5,0xFFFF),Arg0)) {
+ CreateField(BUFF, 0, Multiply(And(ShiftRight(RB5,16),0xFFFF),8), XB5)
+ Store(RE5,BUFF); Store(0,RB5); Return( XB5 )
+ }
+
+ If(LEqual(And(RB6,0xFFFF),Arg0)) {
+ CreateField(BUFF, 0, Multiply(And(ShiftRight(RB6,16),0xFFFF),8), XB6)
+ Store(RE6,BUFF); Store(0,RB6); Return( XB6 )
+ }
+
+ If(LEqual(And(RB7,0xFFFF),Arg0)) {
+ CreateField(BUFF, 0, Multiply(And(ShiftRight(RB7,16),0xFFFF),8), XB7)
+ Store(RE7,BUFF); Store(0,RB7); Return( XB7 )
+ }
+
+ Sleep(5)
+ }
+
+ // If we get here didn't find a matching sequence number
+ Return (Ones)
+}
+```
+
+The following is sample code to transmit a ASYNC request and wait for
+the data in the RX buffer.
+
+```
+Method(ASYC, 0x0, Serialized) {
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(30){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateWordField(BUFF,19,BSQN) // Sequence Number
+
+ // x0 -\> STAT
+ Store(20, LENG)
+ Store(0x0, CMDD) // EC_ASYNC command
+ Local0 = QTXB(BUFF,20) // Copy data to our queue entry and get back SEQN
+ Store(Local0,BSQN) // Sequence packet to read from shared memory
+ Store(ToUUID("330c1273-fde5-4757-9819-5b6539037502"), UUID)
+ Store(Store(BUFF, \\_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (RXDB(Local0)) // Loop through our RX queue till packet completes
+ }
+}
+```
+
+## Recovery and Errors
+
+The eSPI or bus driver is expected to detect if the EC is not responding
+and retry. The FFA driver will report back in the status byte if it
+cannot successfully talk to the secure world. If there are other
+failures generally they should be returned back up through ACPI with a
+value of (Ones) to indicate failure condition. This may cause some
+features to work incorrectly.
+
+It is also expected that the EC has a watchdog if something on the EC is
+hung it should reset and reload on its own. The EC is also responsible
+for monitoring that the system is running within safe parameters. The
+thermal requests and queries are meant to be advisory in nature and EC
+should be able to run independently and safely without any intervention
+from the OS.
+
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/thermal-service.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/thermal-service.md
new file mode 100644
index 0000000..1851d0c
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/thermal-service.md
@@ -0,0 +1,538 @@
+# Thermal Zone Service
+
+Battery temperature and other temperatures are read through a modified
+thermal interface called Microsoft Temperature Sensor that implements
+the _TMP and _DSM functionality. There is also still a generic thermal
+zone interface which has a few more entries for system outside of MPTF.
+
+| **Command** | **Description** |
+| ------------------------ | -------------------------------------------------------------------- |
+| EC_THM_GET_TMP = 0x1 | Returns the thermal zone’s current temperature in tenths of degrees. |
+| EC_THM_SET_THRS = 0x2 | Sets the thresholds for high, low and timeout. |
+| EC_THM_GET_THRS = 0x3 | Get thresholds for low and high points |
+| EC_THM_SET_SCP = 0x4 | Set cooling Policy for thermal zone |
+| EC_THM_GET_VAR = 0x5 | Read DWORD variable related to thermal |
+| EC_THM_SET_VAR = 0x6 | Write DWORD variable related to thermal |
+
+## EC_THM_GET_TMP
+
+The Microsoft Thermal Sensor is a simplified [ACPI Thermal Zone
+object](https://uefi.org/specs/ACPI/6.5/11_Thermal_Management.html?highlight=_tmp),
+it only keeps the temperature input part of the thermal zone. It is used
+as the interface to send temperatures from the hardware to the OS. Like
+the thermal zone, Thermal Sensor also supports getting temperatures
+through _TMP method.
+
+### Input Parameters
+
+Arg0 – Byte Thermal Zone Identifier
+
+### Output Parameters
+
+An Integer containing the current temperature of the thermal zone (in
+tenths of degrees Kelvin)
+
+The return value is the current temperature of the thermal zone in
+tenths of degrees Kelvin. For example, 300.0K is represented by the
+integer 3000.
+
+### FFA ACPI Example
+
+```
+Method (_TMP) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(24){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateByteField(BUFF,19, TMP1) // In – Thermal Zone Identifier
+ CreateField(BUFF,144,32,TMPD) // Out – temperature for TZ
+
+ Store(20, LENG)
+ Store(0x1, CMDD) // EC_THM_GET_TMP
+ Store(1,TMP1)
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID) // Thermal
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (TMPD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_THM_SET_THRS
+
+Update thresholds for thermal zone
+
+The platform should inform the OSPM to read _TMP method through
+Notify(device, 0x80) when **any** of
+below conditions is met:
+
+ - The **Timeout** has been met.
+
+
+
+ - The current temperature crosses the zone specified by
+ **LowTemperature** or **HighTemperature**.
+
+### Input Parameters
+
+Arg0 – Byte Thermal Zone Identifier
+
+Arg1 – Timeout // Integer (DWORD) in mS
+
+Arg2 – LowTemperature // Integer (DWORD) in tenth deg Kelvin
+
+Arg3 - HighTemperature // Integer (DWORD) in tenth deg Kelvin
+
+### Output Parameters
+
+Integer with status
+
+ - 0x00000000: Succeed
+
+ - 0x00000001: Failure, invalid parameter
+
+ - 0x00000002: Failure, unsupported revision
+
+ - 0x00000003: Failure, hardware error
+
+ - Others: Reserved
+
+### FFA ACPI Example
+
+```
+Method(_DSM,4,Serialized,0,UnknownObj, {BuffObj, IntObj,IntObj,PkgObj}) {
+ // Compare passed in UUID to Supported UUID
+ If(LEqual(Arg0,ToUUID(“1f0849fc-a845-4fcf-865c-4101bf8e8d79 ”)))
+ {
+
+ // Implement function 1 which is update threshold
+ If(LEqual(Arg2,One)) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateByteField(BUFF,19, TID1) // In – Thermal Zone Identifier
+ CreateDwordField(BUFF,20,THS1) // In – Timeout in ms
+ CreateDwordField(BUFF,24,THS2) // In – Low threshold tenth Kelvin
+ CreateDwordField(BUFF,28,THS3) // In – High threshold tenth Kelvin
+ CreateField(BUFF,144,32,THSD) // Out – Status from EC
+
+ Store(0x30, LENG)
+ Store(0x2, CMDD) // EC_THM_SET_THRS
+ Store(1,TID1)
+ Store(Arg0,THS1)
+ Store(Arg1,THS2)
+ Store(Arg2,THS3)
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID) // Thermal
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (THSD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+
+## EC_THM_GET_THRS
+
+Read back thresholds that have been set or default thresholds that exist
+on the EC.
+
+### Input Parameters
+
+Arg0 - Thermal ID – Identifier to determine which TZ to read the
+thresholds for
+
+### Output Parameters
+
+Arg0 – Status // 0 on success or neagtive error code
+
+Arg1 – Timeout // Integer (DWORD) in mS
+
+Arg2 – LowTemperature // Integer (DWORD) in tenth deg Kelvin
+
+Arg3 - HighTemperature // Integer (DWORD) in tenth deg Kelvin
+
+### FFA ACPI Example
+```
+Method(_DSM,4,Serialized,0,UnknownObj, {BuffObj, IntObj,IntObj,PkgObj}) {
+ // Compare passed in UUID to Supported UUID
+ If(LEqual(Arg0,ToUUID(“1f0849fc-a845-4fcf-865c-4101bf8e8d79 ”)))
+ {
+ // Implement function 2 which is update threshold
+ If(LEqual(Arg2,Two)) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(34){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateByteField(BUFF,19, TID1) // In – Thermal Zone Identifier
+ CreateField(BUFF,144,128,THSD) // Out – Includes status, timeout, low/high
+
+ Store(20, LENG)
+ Store(0x3, CMDD) // EC_THM_GET_THRS
+ Store(1,TID1)
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID) // Thermal
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (THSD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+ }
+}
+```
+
+## EC_THM_SET_SCP
+
+This optional object is a control method that OSPM invokes to set the
+platform’s cooling mode policy setting.
+
+### Input Parameters
+
+Arg0 - Identifier to determine which TZ to read the thresholds for
+
+Arg1 - Mode An Integer containing the cooling mode policy code
+
+Arg2 - AcousticLimit An Integer containing the acoustic limit
+
+Arg3 - PowerLimit An Integer containing the power limit
+
+### Output Parameters
+
+Arg0 – Status from EC
+
+ - 0x00000000: Succeed
+
+ - 0x00000001: Failure, invalid parameter
+
+ - 0x00000002: Failure, unsupported revision
+
+ - 0x00000003: Failure, hardware error
+
+ - Others: Reserved
+
+### FFA ACPI Example
+```
+Method (_SCP) {
+ // Check to make sure FFA is available and not unloaded
+ If(LEqual(\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(32){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateByteField(BUFF,19, SCP0) // In – Thermal Zone Identifier
+ CreateDwordField(BUFF,20, SCP1) // In – Cooling mode policy
+ CreateDwordField(BUFF,24, SCP2) // In – Acoustic Limit
+ CreateDwordField(BUFF,28, SCP3) // In – Power Limit
+ CreateField(BUFF,144,32, SCPD) // Out – temperature for TZ
+
+ Store(0x30, LENG)
+ Store(0x4, CMDD) // EC_THM_SET_SCP
+ Store(1,SCP0)
+ Store(Arg0,SCP1)
+ Store(Arg1,SCP2)
+ Store(Arg2,SCP3)
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID) // Thermal
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (SCPD)
+ } else {
+ Return(Zero)
+ }
+ } else {
+ Return(Zero)
+ }
+}
+```
+## EC_THM_GET_VAR
+
+This API is to read a variable from the EC related to thermal. Variables
+are defined as GUID’s and include length of variable to read. In the
+case of default MPTF interface it is expecting a 32-bit variable.
+
+### Input Parameters
+
+Arg0 – 128-bit UUID the defines the variable
+
+Arg1 – 16-bit Length field specifies the length of variable in bytes
+
+### Output Parameters
+
+Arg0 – 32-bit status field
+
+ - 0x00000000: Succeed
+
+ - 0x00000001: Failure, invalid parameter
+
+ - 0x00000002: Failure, unsupported revision
+
+ - 0x00000003: Failure, hardware error
+
+ - Others: Reserved
+
+Var – Variable length data must match requested length otherwise should
+return error code
+
+### FFA ACPI Example
+
+```
+Method(GVAR,2,Serialized) {
+ If(LEqual(\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(38){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateByteField(BUFF,19,INST) // Instance ID
+ CreateWordField(BUFF,20,VLEN) // 16-bit variable length
+ CreateField(BUFF,176,128,VUID) // UUID of variable to read
+ CreateField(BUFF,208,64,RVAL) // Output Data
+
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID)
+ Store(38, LENG)
+ Store(0x5, CMDD) // EC_THM_GET_VAR
+ Store(Arg0,INST) // Save instance ID
+ Store(4,VLEN) // Variable is always DWORD here
+ Store(Arg1, VUID)
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (RVAL)
+ }
+ }
+ Return (Ones)
+}
+```
+
+## EC_THM_SET_VAR
+
+This API is to write a variable to the EC related to thermal. Variables
+are defined as GUID’s and include length of variable to write. In the
+case of default MPTF interface it is expecting a 32-bit variable.
+
+### Input Parameters
+
+Arg0 – 128-bit UUID the defines the variable
+
+Arg1 – 16-bit Length field specifies the length of variable in bytes
+
+Var - Variable length field of variable data
+
+### Output Parameters
+
+Arg0 – 32-bit status field
+
+ - 0x00000000: Succeed
+
+ - 0x00000001: Failure, invalid parameter
+
+ - 0x00000002: Failure, unsupported revision
+
+ - 0x00000003: Failure, hardware error
+
+ - Others: Reserved
+
+### FFA ACPI Example
+```
+Method(SVAR,3,Serialized) {
+ If(LEqual(\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(42){})
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18,CMDD) // Command register
+ CreateByteField(BUFF,19,INST) // Instance ID
+ CreateWordField(BUFF,20,VLEN) // 16-bit variable length
+ CreateField(BUFF,176,128,VUID) // UUID of variable to read
+ CreateDwordField(BUFF,38,DVAL) // Data value
+ CreateField(BUFF,208,32,RVAL) // Ouput Data
+
+ Store(ToUUID("31f56da7-593c-4d72-a4b3-8fc7171ac073"), UUID)
+ Store(42, LENG)
+ Store(0x6, CMDD) // EC_THM_SET_VAR
+ Store(Arg0,INST) // Save instance ID
+ Store(4,VLEN) // Variable is always DWORD here
+ Store(Arg1, VUID)
+ Store(Arg2,DVAL)
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (RVAL)
+ }
+ }
+ Return (Ones)
+}
+```
+
+# Fan Service
+
+The new MBTF framework depends on reading and writing variables on the
+EC to allow the EC to make the best decisions on cooling. The
+recommendations from the OS are aggregated on the EC side and decisions
+are made on setting FAN speed based on these.
+
+All the control of fan and thermal parameters is done through variable
+interface using EC_THM_GET_VAR and EC_THM_SET_VAR.
+
+## Fan and Thermal variables
+
+It is optional to implement Dba and Sones.
+
+
+
+
+
+
+| OnTemp |
+ba17b567-c368-48d5-bc6f-a312a41583c1 |
+Lowest temperature at which the fan is turned on. |
+
+RampTemp |
+3a62688c-d95b-4d2d-bacc-90d7a5816bcd |
+Temperature at which the fan starts ramping from min speed. |
+
+MaxTemp |
+dcb758b1-f0fd-4ec7-b2c0-ef1e2a547b76 |
+Temperature at top of fan ramp where fan is at maximum speed. |
+
+CrtTemp |
+218246e7-baf6-45f1-aa13-07e4845256b8 |
+Critical temperature at which we need to shut down the system. |
+
+ProcHotTemp |
+22dc52d2-fd0b-47ab-95b8-26552f9831a5 |
+Temperature at which the EC will assert the PROCHOT notification. |
+
+MinRpm |
+db261c77-934b-45e2-9742-256c62badb7a |
+Minimum RPM FAN speed |
+
+MinDba (Optional) |
+0457a722-58f4-41ca-b053-c7088fcfb89d |
+Minimum Dba from FAN |
+
+MinSones (Optional) |
+311668e2-09aa-416e-a7ce-7b978e7f88be |
+Minimum Sones from FAN |
+
+MaxRpm |
+5cf839df-8be7-42b9-9ac5-3403ca2c8a6a |
+Maximum RPM for FAN |
+
+MaxDba (Optional) |
+372ae76b-eb64-466d-ae6b-1228397cf374 |
+Maximum DBA for FAN |
+
+MaxSones (Optional) |
+6deb7eb1-839a-4482-8757-502ac31b20b7 |
+Maximum Sones for FAN |
+
+ProfileType |
+23b4a025-cdfd-4af9-a411-37a24c574615 |
+Set profile for EC, gaming, quiet, lap, etc |
+
+CurrentRpm |
+adf95492-0776-4ffc-84f3-b6c8b5269683 |
+The current RPM of FAN |
+
+CurrentDba (Optional) |
+4bb2ccd9-c7d7-4629-9fd6-1bc46300ee77 |
+The current Dba from FAN |
+
+CurrentSones (Optional) |
+7719d686-02af-48a5-8283-20ba6ca2e940 |
+The current Sones from FAN |
+
+
+
+
+## ACPI example of Input/Output _DSM
+
+```
+// Arg0 GUID
+// 07ff6382-e29a-47c9-ac87-e79dad71dd82 - Input
+// d9b9b7f3-2a3e-4064-8841-cb13d317669e - Output
+// Arg1 Revision
+// Arg2 Function Index
+// Arg3 Function dependent
+
+Method(_DSM, 0x4, Serialized) {
+ // Input Variable
+ If(LEqual(ToUuid("07ff6382-e29a-47c9-ac87-e79dad71dd82"),Arg0)) {
+ Switch(Arg2) {
+ Case(0) {
+ // We support function 0-3
+ Return(0xf)
+ }
+ Case(1) {
+ Return(GVAR(1,ToUuid("ba17b567-c368-48d5-bc6f-a312a41583c1"))) // OnTemp
+ }
+ Case(2) {
+ Return(GVAR(1,ToUuid("3a62688c-d95b-4d2d-bacc-90d7a5816bcd"))) // RampTemp
+ }
+ Case(3) {
+ Return(GVAR(1,ToUuid("dcb758b1-f0fd-4ec7-b2c0-ef1e2a547b76"))) // MaxTemp
+ }
+ }
+ Return(Ones)
+ }
+
+ // Output Variable
+ If(LEqual(ToUuid("d9b9b7f3-2a3e-4064-8841-cb13d317669e"),Arg0)) {
+ Switch(Arg2) {
+ Case(0) {
+ // We support function 0-3
+ Return(0xf)
+ }
+ Case(1) {
+ Return(SVAR(1,ToUuid("ba17b567-c368-48d5-bc6f-a312a41583c1"),Arg3)) // OnTemp
+ }
+
+ Case(2) {
+ Return(SVAR(1,ToUuid("3a62688c-d95b-4d2d-bacc-90d7a5816bcd"),Arg3)) // RampTemp
+ }
+
+ Case(3) {
+ Return(SVAR(1,ToUuid("dcb758b1-f0fd-4ec7-b2c0-ef1e2a547b76"),Arg3)) // MaxTemp
+ }
+ }
+ Return(Ones)
+ }
+ Return (Ones)
+}
+```
diff --git a/bookshelf/Shelf 3 Specifications/EC Interface/src/ucsi-interface.md b/bookshelf/Shelf 3 Specifications/EC Interface/src/ucsi-interface.md
new file mode 100644
index 0000000..50468b6
--- /dev/null
+++ b/bookshelf/Shelf 3 Specifications/EC Interface/src/ucsi-interface.md
@@ -0,0 +1,114 @@
+# UCSI Interface
+
+EC must have the ability to interface with a discrete PD controller to
+negotiate power contracts/alt-modes with port partner
+
+See the UCSI specification for commands that are required in all UCSI
+implementations.
+
+[USB-C Connector System Software Interface (UCSI) Driver - Windows
+drivers | Microsoft
+Learn](https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/ucsi)
+
+In addition to the commands marked as **Required**, Windows requires
+these commands:
+
+ - GET_ALTERNATE_MODES
+
+ - GET_CAM_SUPPORTED
+
+ - GET_PDOS
+
+ - SET_NOTIFICATION_ENABLE: The system or controller must support the
+ following notifications within SET_NOTIFICATION_ENABLE:
+
+ - Supported Provider Capabilities Change
+
+ - Negotiated Power Level Change
+
+ - GET_CONNECTOR_STATUS: The system or controller must support these
+ connector status changes within GET_CONNECTOR_STATUS:
+
+ - Supported Provider Capabilities Change
+
+ - Negotiated Power Level Change
+
+
+
+## UCSI ACPI Interface
+
+
+
+### Shared Mailbox Interface
+
+The following table is the reserved memory structure that must be
+reserved and shared with the EC for communication. When using FF-A this
+memory region must be statically carved out and 4K aligned and directly
+accessible by secure world.
+
+| **Offset (Bytes)** | **Mnemonic** | **Description** | **Direction** | **Size (bits)** |
+| ------------------ | ------------ | --------------------------------------------------------- | ------------- | --------------- |
+| 0 | VERSION | UCSI Version Number | PPM->OPM | 16 |
+| 2 | RESERVED | Reserved | N/A | 16 |
+| 4 | CCI | USB Type-C Command Status and Connector Change Indication | PPM->OPM | 32 |
+| 8 | CONTROL | USB Type-C Control | OPM->PPM | 64 |
+| 16 | MESSAGE IN | USB Type-C Message In | PPM->OPM | 128 |
+| 32 | MESSAGE OUT | USB Type-C Message Out | OPM->PPM | 128 |
+
+### ACPI Definitions
+```
+Device(USBC) {
+ Name(_HID,EISAID(“USBC000”))
+ Name(_CID,EISAID(“PNP0CA0”))
+ Name(_UID,1)
+ Name(_DDN, “USB Type-C”)
+ Name(_ADR,0x0)
+
+ OperationRegion(USBC, SystemMemory, 0xFFFF0000, 0x30)
+ Field(USBC,AnyAcc,Lock,Preserve)
+ {
+ // USB C Mailbox Interface
+ VERS,16, // PPM-\>OPM Version
+ RES, 16, // Reservied
+ CCI, 32, // PPM-\>OPM CCI Indicator
+ CTRL,64, // OPM-\>PPM Control Messages
+ MSGI,128, // OPM-\>PPM Message In
+ MSGO,128, // PPM-\>OPM Message Out
+ }
+
+ Method(_DSM,4,Serialized,0,UnknownObj, {BuffObj, IntObj,IntObj,PkgObj})
+ {
+ // Compare passed in UUID to Supported UUID
+ If(LEqual(Arg0,ToUUID(“6f8398c2-7ca4-11e4-ad36-631042b5008f”)))
+ {
+ // Use FFA to send Notification event down to copy data to EC
+ If(LEqual(\\_SB.FFA0.AVAL,One)) {
+ Name(BUFF, Buffer(144){}) // Create buffer for send/recv data
+ CreateByteField(BUFF,0,STAT) // Out – Status for req/rsp
+ CreateByteField(BUFF,1,LENG) // In/Out – Bytes in req, updates bytes returned
+ CreateField(BUFF,16,128,UUID) // UUID of service
+ CreateByteField(BUFF,18, CMDD) // In – First byte of command
+ CreateField(BUFF,144,1024,FIFD) // Out – Msg data
+
+ CreateField(BUFF,0x0,128,UUID)
+ // Create USCI Doorbell Event
+
+ Store(20, LENG)
+ Store(0x0, CMDD) // UCSI set doorbell
+ Store(ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), UUID) // UCSI
+ Store(Store(BUFF, \_SB_.FFA0.FFAC), BUFF)
+
+ If(LEqual(STAT,0x0) ) // Check FF-A successful?
+ {
+ Return (FIFD)
+ } else {
+ Return(error)?
+ }
+ } // End AVAL
+ } // End UUID
+ } // End DSM
+}
+
+```
+