johnfanv2 / LenovoLegionLinux

Driver and tools for controlling Lenovo Legion laptops in Linux including fan control and power mode.
https://github.com/johnfanv2/LenovoLegionLinux
GNU General Public License v2.0
1.68k stars 59 forks source link

Legion S7-15ACH6 | Module fails to load on Nobara 37 #13

Open cobaltbee opened 1 year ago

cobaltbee commented 1 year ago

Hello, thanks for the great project, I couldn't believe my eyes when I saw the post on r/LenovoLegion, and I hope mods will sticky your thread soon for more visibilty.

I have a Legion S7-15ACH6 - Type 82K8 aka 2021 Slim 7 that unfortunately has problems loading the module. I have tried the 'forceloadmodule' option mentioned in another thread here, but no luck. Let me know if you need any further details from me, glad to provide whatever you need.

LenovoLegionLinux/kernel_module on  main via C v12.2.1-gcc 
❯ make
make -C /lib/modules/6.1.6-203.fsync.fc37.x86_64/build M=/home/me/LenovoLegionLinux/kernel_module modules
make[1]: Entering directory '/usr/src/kernels/6.1.6-203.fsync.fc37.x86_64'
  CC [M]  /home/me/LenovoLegionLinux/kernel_module/legion-laptop.o
  MODPOST /home/me/LenovoLegionLinux/kernel_module/Module.symvers
  CC [M]  /home/me/LenovoLegionLinux/kernel_module/legion-laptop.mod.o
  LD [M]  /home/me/LenovoLegionLinux/kernel_module/legion-laptop.ko
  BTF [M] /home/me/LenovoLegionLinux/kernel_module/legion-laptop.ko
Skipping BTF generation for /home/me/LenovoLegionLinux/kernel_module/legion-laptop.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/kernels/6.1.6-203.fsync.fc37.x86_64'
LenovoLegionLinux/kernel_module on  main via C v12.2.1-gcc 
❯ ls -laFtrh
total 1.4M
-rw-r--r-- 1 me me  894 Jan 23 19:34 Makefile
-rw-r--r-- 1 me me 9.6K Jan 23 19:34 legion-laptop-unused-snippets.c
-rw-r--r-- 1 me me  87K Jan 23 19:34 legion-laptop.c
drwxr-xr-x 1 me me  348 Jan 23 19:34 ../
-rw-r--r-- 1 me me 474K Jan 24 12:01 legion-laptop.o
-rw-r--r-- 1 me me  47K Jan 24 12:01 .legion-laptop.o.cmd
-rw-r--r-- 1 me me  244 Jan 24 12:01 .legion-laptop.mod.cmd
-rw-r--r-- 1 me me   60 Jan 24 12:01 legion-laptop.mod
-rw-r--r-- 1 me me  201 Jan 24 12:01 .modules.order.cmd
-rw-r--r-- 1 me me   61 Jan 24 12:01 modules.order
-rw-r--r-- 1 me me  258 Jan 24 12:01 .Module.symvers.cmd
-rw-r--r-- 1 me me    0 Jan 24 12:01 Module.symvers
-rw-r--r-- 1 me me 1.2K Jan 24 12:01 legion-laptop.mod.c
-rw-r--r-- 1 me me  94K Jan 24 12:01 legion-laptop.mod.o
-rw-r--r-- 1 me me  38K Jan 24 12:01 .legion-laptop.mod.o.cmd
-rw-r--r-- 1 me me  337 Jan 24 12:01 .legion-laptop.ko.cmd
-rw-r--r-- 1 me me 565K Jan 24 12:01 legion-laptop.ko
drwxr-xr-x 1 me me  582 Jan 24 12:01 ./
LenovoLegionLinux/kernel_module on  main via C v12.2.1-gcc 
❯ sudo make reloadmodule
[sudo] password for me: 
rmmod legion-laptop.ko || true
rmmod: ERROR: Module legion_laptop is not currently loaded
insmod legion-laptop.ko
...
[  366.773137] legion_laptop 0.1 starts loading
[  366.773141] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82K8; DMI_BIOS_VERSION:HACN39WW
[  366.773196] legion PNP0C09:00: legion_laptop platform driver 0.1 probing
[  366.773198] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82K8; DMI_BIOS_VERSION:HACN39WW
[  366.773201] legion PNP0C09:00: is_denied: 0; is_allowed: 0; do_load_by_list: 0; do_load: 0
[  366.773202] legion PNP0C09:00: Module not useable for this laptop because it is not in allowlist. Notify maintainer if you want to add your device or force load with param force.
[  366.773204] legion PNP0C09:00: legion_laptop not loaded for this device
[  366.773238] legion: probe of PNP0C09:00 failed with error -12
LenovoLegionLinux/kernel_module on  main via C v12.2.1-gcc 
❯ sudo make forcereloadmodule
rmmod legion-laptop.ko || true
insmod legion-laptop.ko force=1
...
[  366.773137] legion_laptop 0.1 starts loading
[  366.773141] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82K8; DMI_BIOS_VERSION:HACN39WW
[  366.773196] legion PNP0C09:00: legion_laptop platform driver 0.1 probing
[  366.773198] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82K8; DMI_BIOS_VERSION:HACN39WW
[  366.773201] legion PNP0C09:00: is_denied: 0; is_allowed: 0; do_load_by_list: 0; do_load: 0
[  366.773202] legion PNP0C09:00: Module not useable for this laptop because it is not in allowlist. Notify maintainer if you want to add your device or force load with param force.
[  366.773204] legion PNP0C09:00: legion_laptop not loaded for this device
[  366.773238] legion: probe of PNP0C09:00 failed with error -12
[  398.045427] legion_laptop 0.1 starts unloading
[  398.045456] legion_laptop 0.1 unloaded
[  398.067961] legion_laptop 0.1 starts loading
[  398.067965] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82K8; DMI_BIOS_VERSION:HACN39WW
[  398.068016] legion PNP0C09:00: legion_laptop platform driver 0.1 probing
[  398.068019] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82K8; DMI_BIOS_VERSION:HACN39WW
[  398.068022] legion PNP0C09:00: is_denied: 0; is_allowed: 0; do_load_by_list: 0; do_load: 1
[  398.068025] legion PNP0C09:00: legion_laptop is forced to load.
[  398.068027] legion PNP0C09:00: legion_laptop is forced to load and would otherwise be not loaded
[  398.068046] Succeffuly mapped embedded controller: 0xfe00d400 to virtual 0x0000000006fd8256
[  398.068100] legion PNP0C09:00: Expected EC chip id 0x8227 but read 0x5576
[  398.068103] Unloading legion ecram
[  398.068104] Unmapping embedded controller memory at 0xfe00d400 at virtual 0x0000000006fd8256
[  398.068106] Unloading legion ecram done
[  398.068108] Unloading legion shared
[  398.068109] Unloading legion shared done
[  398.068110] legion PNP0C09:00: legion_laptop not loaded for this device
[  398.068150] legion: probe of PNP0C09:00 failed with error -12

Info about the system:

Top of 'dmesg'

[    0.000000] Linux version 6.1.6-203.fsync.fc37.x86_64 (mockbuild@dd663ccef6e54b6aafb53127d00e9c61) (gcc (GCC) 12.2.1 20221121 (Red Hat 12.2.1-4), GNU ld version 2.38-25.fc37) #1 SMP PREEMPT_DYNAMIC TKG Thu Jan 19 19:16:07 UTC 2023
[    0.000000] Command line: BOOT_IMAGE=(hd0,gpt2)/vmlinuz-6.1.6-203.fsync.fc37.x86_64 root=UUID=xxx ro rootflags=subvol=@ rd.driver.blacklist=nouveau modprobe.blacklist=nouveau nvidia-drm.modeset=1
❯ inxi -xzF
System:
  Kernel: 6.1.6-203.fsync.fc37.x86_64 arch: x86_64 bits: 64 compiler: gcc
    v: 2.38-25.fc37 Desktop: GNOME v: 43.2 Distro: Nobara release 37 (Thirty
    Seven)
Machine:
  Type: Laptop System: LENOVO product: 82K8 v: Legion S7 15ACH6
    serial: <superuser required>
  Mobo: LENOVO model: LNVNB161216 v: SDK0T76461WIN
    serial: <superuser required> UEFI: LENOVO v: HACN39WW date: 09/21/2022
Battery:
  ID-1: BAT0 charge: 27.7 Wh (38.5%) condition: 72.0/71.0 Wh (101.4%)
    volts: 15.4 min: N/A model: SMP L20M4PD3 status: charging
CPU:
  Info: 6-core model: AMD Ryzen 7 5800H with Radeon Graphics bits: 64
    type: MT MCP arch: Zen 3 rev: 0 cache: L1: 384 KiB L2: 3 MiB L3: 16 MiB
  Speed (MHz): avg: 1427 high: 3200 min/max: 1200/4462 boost: disabled
    cores: 1: 1200 2: 1200 3: 3200 4: 1395 5: 1200 6: 1200 7: 1743 8: 1200
    9: 1198 10: 1200 11: 1198 12: 1200 bogomips: 76662
  Flags: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 svm
Graphics:
  Device-1: NVIDIA GA106M [GeForce RTX 3060 Mobile / Max-Q] vendor: Lenovo
    driver: nvidia v: 525.85.05 arch: Ampere bus-ID: 01:00.0
  Device-2: AMD Cezanne [Radeon Vega Series / Radeon Mobile Series]
    vendor: Lenovo driver: amdgpu v: kernel arch: GCN-5.1 bus-ID: 05:00.0
    temp: 42.0 C
  Device-3: IMC Networks Integrated Camera type: USB driver: uvcvideo
    bus-ID: 3-3:2
  Display: wayland server: X.Org v: 22.1.7 with: Xwayland v: 22.1.7
    compositor: gnome-shell driver: X: loaded: amdgpu,nvidia
    unloaded: fbdev,modesetting,nouveau,vesa dri: radeonsi gpu: amdgpu
    resolution: 1920x1080~165Hz
  API: OpenGL v: 4.6 Mesa 22.3.3 renderer: AMD Radeon Graphics (renoir LLVM
    15.0.6 DRM 3.49 6.1.6-203.fsync.fc37.x86_64) direct render: Yes
Audio:
  Device-1: NVIDIA GA106 High Definition Audio vendor: Lenovo
    driver: snd_hda_intel v: kernel bus-ID: 01:00.1
  Device-2: AMD ACP/ACP3X/ACP6x Audio Coprocessor vendor: Lenovo driver: N/A
    bus-ID: 05:00.5
  Device-3: AMD Family 17h/19h HD Audio vendor: Lenovo driver: snd_hda_intel
    v: kernel bus-ID: 05:00.6
  Sound API: ALSA v: k6.1.6-203.fsync.fc37.x86_64 running: yes
  Sound Server-1: PulseAudio v: 16.1 running: no
  Sound Server-2: PipeWire v: 0.3.64 running: yes
Network:
  Device-1: Realtek RTL8852AE 802.11ax PCIe Wireless Network Adapter
    vendor: Lenovo driver: rtw89_8852ae v: kernel port: 2000 bus-ID: 02:00.0
  IF: wlp2s0 state: up mac: <filter>
Bluetooth:
  Device-1: Realtek Bluetooth Radio type: USB driver: btusb v: 0.8
    bus-ID: 1-3:3
  Report: rfkill ID: hci0 rfk-id: 4 state: up address: see --recommends
Drives:
  Local Storage: total: 476.94 GiB used: 288.5 GiB (60.5%)
  ID-1: /dev/nvme0n1 vendor: Samsung model: MZVLB512HBJQ-000L2
    size: 476.94 GiB temp: 33.9 C
Partition:
  ID-1: / size: 475.35 GiB used: 288.18 GiB (60.6%) fs: btrfs dev: /dev/dm-0
    mapped: luks-xxx
  ID-2: /boot size: 973.4 MiB used: 317.3 MiB (32.6%) fs: ext4
    dev: /dev/nvme0n1p2
  ID-3: /boot/efi size: 598.8 MiB used: 17.3 MiB (2.9%) fs: vfat
    dev: /dev/nvme0n1p1
  ID-4: /home size: 475.35 GiB used: 288.18 GiB (60.6%) fs: btrfs
    dev: /dev/dm-0 mapped: luks-xxx
Swap:
  ID-1: swap-1 type: zram size: 13 GiB used: 0 KiB (0.0%) dev: /dev/zram0
Sensors:
  System Temperatures: cpu: N/A mobo: N/A
  Fan Speeds (RPM): N/A
Info:
  Processes: 402 Uptime: 24m Memory: 14.99 GiB used: 3.58 GiB (23.9%)
  Init: systemd target: graphical (5) Compilers: gcc: 12.2.1 Packages: 20
  note: see --rpm Shell: Bash v: 5.2.15 inxi: 3.3.24
❯ sudo lshw
[sudo] password for me: 
nob                    
    description: Notebook
    product: 82K8 (LENOVO_MT_82K8_BU_idea_FM_Legion S7 15ACH6)
    vendor: LENOVO
    version: Legion S7 15ACH6
    serial: xxx
    width: 64 bits
    capabilities: smbios-3.3.0 dmi-3.3.0 smp vsyscall32
    configuration: administrator_password=disabled boot=normal chassis=notebook family=Legion S7 15ACH6 frontpanel_password=disabled keyboard_password=disabled power-on_password=disabled sku=LENOVO_MT_82K8_BU_idea_FM_Legion S7 15ACH6 uuid=xxx
  *-core
       description: Motherboard
       product: LNVNB161216
       vendor: LENOVO
       physical id: 0
       version: SDK0T76461WIN
       serial: xxx
       slot: Base Board Chassis Location
     *-cpu
          description: CPU
          product: AMD Ryzen 7 5800H with Radeon Graphics
          vendor: Advanced Micro Devices [AMD]
          physical id: 6
          bus info: cpu@0
          version: AMD Ryzen 7 5800H with Radeon Graphics
          serial: Null
          slot: FP6
          size: 2553MHz
          capacity: 4462MHz
          width: 64 bits
          clock: 100MHz
          capabilities: lm fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp x86-64 constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip pku ospke vaes vpclmulqdq rdpid overflow_recov succor smca fsrm cpufreq
          configuration: cores=8 enabledcores=8 threads=16
     *-firmware
          description: BIOS
          vendor: LENOVO
          physical id: d
          version: HACN39WW
          date: 09/21/2022
          size: 128KiB
          capacity: 16MiB
          capabilities: acpi usb biosbootspecification netboot uefi
johnfanv2 commented 1 year ago

It failed because it expected the ID of the embedded controller to be 0x8227, but it read 0x5576. This model HACN BIOS firmware also does not seems to supported by the Windows tools LegionFanControl. It is one of the rare cases.

Maybe this model uses another chip. If you want to try to find the addresses in this chip, I could guide you through. It roughly works like that. Either, it can be easy, because you will find the embedded controller will use the same program/memory layout. Or, it is more complicated because it is completely different.

Disassembling ACPI tables

# Install requiered tools
sudo apt install acpica-tools
# Create folder for all the new files
mkdir acpi_re
cd acpi_re

# List ACPI tables and copy them
ls /sys/firmware/acpi/tables/
sudo cp --no-preserve=mode /sys/firmware/acpi/tables/*SDT* .

# Disassemble tables to output DSDT.dsl
iasl -e SSDT* -d DSDT

Then upload files.

Find Mapped Memory Address of Embedded Controller

Find the part for the embedded controller. It will contain something like this.

Device (EC0)
    Name (_HID, EisaId ("PNP0C09") /* Embedded Controller Device */)  // _HID: Hardware ID
    Name (_UID, One)  // _UID: Unique ID

Then find the regions used by the embedded controller. There are lots of other regions, but only these are interesting that are within the scope/braces of the embedded controller.

You will find something similar to this:

OperationRegion (ERAM, EmbeddedControl, Zero, 0xFF)

OperationRegion (ECMS, SystemIO, 0x72, 0x02)

OperationRegion (ERAX, SystemMemory, 0xFE00D400, 0xFF)
- mapped into memory at 0xFE00D400
- region with most of the fields defined

OperationRegion (ECB2, SystemMemory, 0xFF00D520, 0xFF)
- mapped into memory at 0xFF00D520
- region with most of the fields defined

This will show that registers/memory of the embedded controller is mapped to (CPU) memory address space. Note that these regions described in the ACPI tables above are only the registers/memory used directly in ACPI.

Often, much more registers/memory of the embedded controller are mapped to (CPU). Usually, these are before or after the regions mentioned in the ACPI tables.

Observing what Changes to Associate Memory Addresses With Functions

Now we can read the memory mapped regions. Then we change something, e.g.

...

cobaltbee commented 1 year ago

OK, thanks. Here you go, please see attached.

I see the first section you mention, but grep'ing for 'ERAM' and 'EmbeddedControl' shows nothing.

s7_15ach6_acpi_re.tar.gz

johnfanv2 commented 1 year ago

I had a lock at the files and found the string "embedded controller". It seems to be at the same memory address as others. I pushed a version (to main), that allows you just try it in readonly mode.

Try

# pull newest version
cd kernel_moodule
make
sudo make forcereloadmodulereadonly
cat /sys/kernel/debug/legion/fancurve

and check if this outputs a sensible fan curve. Otherwise, one would have to find different addresses in your different embedded controller.

cobaltbee commented 1 year ago

Thanks a lot, I really appreciate it. The module now loads, although there are some errors...

[25137.962671] legion_laptop 0.1 starts loading
[25137.962677] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82K8; DMI_BIOS_VERSION:HACN39WW
[25137.962742] legion PNP0C09:00: legion_laptop platform driver 0.1 probing
[25137.962744] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82K8; DMI_BIOS_VERSION:HACN39WW
[25137.962747] legion PNP0C09:00: is_denied: 0; is_allowed: 1; do_load_by_list: 1; do_load: 1
[25137.962748] legion PNP0C09:00: legion_laptop is forced to load.
[25137.962749] legion PNP0C09:00: Using configuration for system: HACN
[25137.962764] Succeffuly mapped embedded controller: 0xfe00d400 to virtual 0x00000000e53d72d3
[25137.962767] Unexpected read at offset 8192 into EC RAM
[25137.962768] Error reading EC RAM at 0x2000
[25137.962769] Unexpected read at offset 8193 into EC RAM
[25137.962769] Error reading EC RAM at 0x2001
[25137.962770] legion PNP0C09:00: Read embedded controller ID 0x0
[25137.962771] legion PNP0C09:00: Skipped checking embedded controller id
[25137.962772] legion PNP0C09:00: Creating debugfs inteface
[25137.962778] Creating sysfs inteface
[25137.962780] Creating hwmon interface
[25137.962830] Creating platform profile support
[25137.962833] Init WMI driver support
[25137.962862] legion_wmi 887B54E3-DDDC-4B2C-8B88-68A26A8835D0: Register after probing for WMI.
[25137.962884] legion_wmi BFD42481-AEE3-4501-A107-AFB68425C5F8: Register after probing for WMI.
[25137.962892] legion_wmi BFD42481-AEE3-4502-A107-AFB68425C5F8: Register after probing for WMI.
[25137.962901] legion_wmi D062906B-12D4-4510-999D-4831EE80E985: Register after probing for WMI.
[25137.962909] legion_wmi BC72A435-E8C1-4275-B3E2-D8B8074ABA59: Register after probing for WMI.
[25137.962917] legion_wmi 10AFC6D9-EA8B-4590-A2E7-1CD3C84BB4B1: Register after probing for WMI.
[25137.962924] legion_wmi D320289E-8FEA-41E0-86F9-611D83151B5F: Register after probing for WMI.
[25137.962944] legion PNP0C09:00: legion_laptop loaded for this device

... but the fan curve isn't right, and using setmyfancurve.sh doesn't seem to change anything.

LenovoLegionLinux on  main 
❯ sudo ./setmyfancurve.sh 
MODEL
Legion S7 15ACH6
BIOS
HACN39WW

Using hwmon directory: /sys/module/legion_laptop/drivers/platform:legion/PNP0C09:00/hwmon/hwmon7
Writing fancurve succesful!
EC Chip ID: 0
EC Chip Version: 0
legion_laptop version: 0.1
legion_laptop features: fancurve powermode platformprofile platformprofilenotify minifancurve
legion_laptop ec_readonly: 0
minifancurve on cool: error
lock fan controller: false
enable maximumfanspeed: false
enable maximumfanspeed status: 0
fan curve current point id: 10
fan curve points size: 10
Current fan curve in hardware (embedded controller):
rpm1|rpm2|acceleration|deceleration|cpu_min_temp|cpu_max_temp|gpu_min_temp|gpu_max_temp|ic_min_temp|ic_max_temp
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
25500    25500   255     255     255     255     255     255     255     255
=====================
Writing fancurve succesful!
MODEL
Legion S7 15ACH6
BIOS
HACN39WW
johnfanv2 commented 1 year ago

It seems like your embedded controller uses different addresses or is a totally different chip. Try pulling, compiling, loading again (I fixed dumping the whole EC memory) and run

cat /sys/kernel/debug/legion/ecmemory | hexdump -C

before and after you change the power mode with Fn+Q. Try to find which values change and which could represent the fan curve.

olilag commented 3 months ago

Hi, are there any updates for this issue? If you'd like any more data from real hardware I have this laptop and am open for any help.