Skip to content

Instantly share code, notes, and snippets.

@HorstBaerbel
Last active January 16, 2024 15:16
Show Gist options
  • Save HorstBaerbel/427a814c263f2d88a9c5092cc7363241 to your computer and use it in GitHub Desktop.
Save HorstBaerbel/427a814c263f2d88a9c5092cc7363241 to your computer and use it in GitHub Desktop.
Monitor Embedded Controller (EC) on Linux via ACPI calls through acpi_call kernel module
#!/usr/bin/env python
"""Dump a range of Embedded Controller memory via ACPI. Requires "acpi_call" kernel module to be loaded. By HorstBaerbel (https://github.com/HorstBaerbel) in 2018."""
import re
import sys
import time
import argparse
output = '\033[0m'
values = {}
def auto_int(x):
return int(x, 0)
def stdout_print(s):
global output
output += s
def stdout_clr():
global output
output = '\033[0m'
def stdout_flush():
global output
sys.stdout.write(output)
sys.stdout.flush()
def stdout_color(color):
stdout_print('\033[{}m'.format(color))
def call_acpi(command):
with open('/proc/acpi/call', 'w') as acpi_call:
acpi_call.write(command)
acpi_call.close()
with open('/proc/acpi/call') as acpi_call:
response = acpi_call.read()
acpi_call.close()
return response
def monitor_ec(startaddr, endaddr, interval):
global values
for addr in range(startaddr, endaddr+1):
values[addr - startaddr] = '-- '
while True:
stdout_clr()
stdout_print(' Base ')
for byteAddr in range(0, 16):
stdout_print('{0:02X} '.format(byteAddr))
stdout_print('\n--------')
for byteAddr in range(0, 16):
stdout_print('---')
stdout_print('\n')
counter = 0;
for addr in range(startaddr, endaddr+1):
cmd = '\_SB.PCI0.LPCB.EC0.RRAM {}'.format(hex(addr))
result = call_acpi(cmd)
if (counter == 0):
stdout_color(0)
stdout_print('0x{0:04X}: '.format(addr))
value = '-- '
if (len(result) > 0):
value = '{0:02X} '.format(int(result.split('\x00')[0], 16))
if (values[addr - startaddr] != value):
values[addr - startaddr] = value
stdout_color(91)
else:
stdout_color(0)
stdout_print(value)
counter += 1
if (counter == 16):
counter = 0
stdout_print('\n')
stdout_flush();
time.sleep(interval)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('start', type=auto_int, default=0x500, help='Start adress of the range in hex (e.g. 0x500)')
parser.add_argument('end', type=auto_int, default=0x5ff, help='End adress of the range in hex (e.g. 0x5ff)')
parser.add_argument('-i', '--interval', type=float, default=1.0, help='Update interval in seconds (e.g. 1.5)')
args = parser.parse_args()
try:
monitor_ec(args.start, args.end, args.interval)
except (KeyboardInterrupt, SystemExit):
sys.exit();
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment