# MSI GE40 laptop ACPI tables and firmware bugs

## gemarcano

For the last couple of weeks I've been looking at improving Gentoo's performance on this new laptop. Thankfully, as I commented here, Gentoo now runs on this hardware. As expected from a Windows laptop, not everything is perfect. My biggest concern right now is that my battery life is dismal and suspend doesn't quite work right (it suspends and in about 2 minutes or less comes back online). I've checked the kernel configuration and all of the appropriate parameters appear to be in place for supporting power management and suspend. In part, the power issue may be related to the kernel's inability to kill the discrete Nvidia GTX 760M (I'm reluctant to use the Nvidia blob right now and Nouveau blows up spectacularly, possibly because the intel graphics driver is already loaded-- this machine supports Optimus). That having been said, I've been reading through the kernel output, and I'm getting some interesting bits, like:

```
[Firmware Bug]: ACPI: BIOS _OSI(Linux) query ignored
```

There are also some ACPI  and kernel driver conflicts with regards to SMBUS, but those appear to be expected based on what I've found around the web (someone correct me if I'm wrong). Having run into this ancient topic, I decided to try working with the ACPI tables. I'm writing this post and topic as a way to log my progress through this mess.

First of all, I did the following as root:

```
cat /sys/firmware/acpi/tables/DSDT > dsdt.dat

iasl -d dsdt.dat 

Intel ACPI Component Architecture

ASL Optimizing Compiler version 20130117-64 [Nov 13 2013]

Copyright (c) 2000 - 2013 Intel Corporation

Loading Acpi table from file dsdt.dat

Acpi table [DSDT] successfully installed and loaded

Pass 1 parse of [DSDT]

Pass 2 parse of [DSDT]

Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)

Parsing completed

Found 10 external control methods, reparsing with new information

Pass 1 parse of [DSDT]

Pass 2 parse of [DSDT]

Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)

Parsing completed

Disassembly completed

ASL Output:    dsdt.dsl - 565906 bytes
```

Well, now I have the disassembled ACPI code being run. I tried to compile it back, and I got this:

```
iasl -tc dsdt.dsl 

Intel ACPI Component Architecture

ASL Optimizing Compiler version 20130117-64 [Nov 13 2013]

Copyright (c) 2000 - 2013 Intel Corporation

dsdt.dsl  11357:                     }

Error    4124 -                     ^ syntax error, unexpected '}', expecting '('

dsdt.dsl  11379:                     }

Error    4124 -                     ^ syntax error, unexpected '}', expecting '('

dsdt.dsl  11523:                         }

Error    4124 -                         ^ syntax error, unexpected '}', expecting '('

dsdt.dsl  12053:                     }

Error    4124 -                     ^ syntax error, unexpected '}', expecting '('

dsdt.dsl  13234:                     }

Error    4124 -                     ^ syntax error, unexpected '}', expecting '('

dsdt.dsl  13248:                     }

Error    4124 -                     ^ syntax error, unexpected '}', expecting '('

dsdt.dsl  14469:             Arg0

Error    4124 -                ^ syntax error, unexpected PARSEOP_ARG0

dsdt.dsl  16080:     If (SS1)

Error    4124 -      ^ syntax error, unexpected PARSEOP_IF

dsdt.dsl  16091:     If (SS3)

Error    4124 -      ^ syntax error, unexpected PARSEOP_IF

dsdt.dsl  16144: 

Error    4124 - syntax error, unexpected $end and premature End-Of-File

ASL Input:     dsdt.dsl - 16145 lines, 534486 bytes, 6834 keywords

Hex Dump:      dsdt.hex - 216 bytes

Compilation complete. 10 Errors, 0 Warnings, 0 Remarks, 0 Optimizations
```

Well crap.

10 errors don't look too bad, right? Some of the errors are related to the code

```
                    If (CondRefOf (\_SB.PCI0.SDHC.WI01.PS0X))

                    {

                        PS0X

                    }
```

Specifically the PS0X line. Near the top this line is mentioned to be an external method with no parameters, and seeing that the error is complaining about missing parentheses, I just added an opening and closing parentheses to the PS0X line (disclaimer: I haven't yet studied up on the proper syntax for ASL). I tried recompiling the code, hopefully seeing less errors now. I tried with one change first, and the error number went down to 9! I changed the rest and saved to a file dsdt2.dsl... and hell broke loose.

```
iasl -tc dsdt2.dsl

Intel ACPI Component Architecture

ASL Optimizing Compiler version 20130117-64 [Nov 13 2013]

Copyright (c) 2000 - 2013 Intel Corporation

dsdt2.dsl   1762:                 If (PICM)

Error    4084 -   Object does not exist ^  (PICM)

dsdt2.dsl   2159:                 If (^XHC.CUID (Arg0))

Error    4085 -                              ^ Object not found or not accessible from scope (^XHC.CUID)

dsdt2.dsl   2161:                     Return (^XHC.POSC (Arg1, Arg2, Arg3))

Error    4085 -                                      ^ Object not found or not accessible from scope (^XHC.POSC)

dsdt2.dsl   2169:                             ^XHC.XSEL ()

Error    4085 -                                      ^ Object not found or not accessible from scope (^XHC.XSEL)

dsdt2.dsl   2190:                                 NHPG ()

Error    4084 -               Object does not exist ^  (NHPG)

dsdt2.dsl   2195:                                 NPME ()

Error    4084 -               Object does not exist ^  (NPME)

dsdt2.dsl   3527:                                 PNOT ()

Error    4084 -               Object does not exist ^  (PNOT)

dsdt2.dsl   3838:                                     P8XH (Zero, 0x99)

Error    4084 -                   Object does not exist ^  (P8XH)

dsdt2.dsl   4006:                                 Return (GPRW (0x1B, 0x03))

Error    4084 -                       Object does not exist ^  (GPRW)

dsdt2.dsl   4027:                             P8XH (Zero, 0x77)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4051:                             P8XH (Zero, 0x80)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4058:                             P8XH (Zero, 0x81)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4060:                             PTHR (One)

Error    4084 -           Object does not exist ^  (PTHR)

dsdt2.dsl   4066:                             P8XH (Zero, 0x82)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4068:                             PTHR (Zero)

Error    4084 -           Object does not exist ^  (PTHR)

dsdt2.dsl   4074:                             P8XH (Zero, 0x83)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4079:                             PNOT ()

Error    4084 -           Object does not exist ^  (PNOT)

dsdt2.dsl   4085:                             P8XH (Zero, 0x84)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4094:                             P8XH (Zero, 0x85)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4102:                             P8XH (Zero, 0x86)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4108:                             P8XH (Zero, 0x87)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4126:                             P8XH (Zero, 0x88)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4132:                             P8XH (Zero, 0x89)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4138:                             P8XH (Zero, 0x8A)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4146:                             P8XH (Zero, 0x8B)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4152:                             P8XH (Zero, 0x8C)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4158:                             P8XH (Zero, 0x90)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4164:                             P8XH (Zero, 0xB4)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4172:                             P8XH (Zero, 0xB5)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4178:                             P8XH (Zero, 0xB6)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4185:                             P8XH (Zero, 0xB7)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4187:                             BRTN (0x87)

Error    4084 -           Object does not exist ^  (BRTN)

dsdt2.dsl   4194:                             P8XH (Zero, 0xB8)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4196:                             BRTN (0x86)

Error    4084 -           Object does not exist ^  (BRTN)

dsdt2.dsl   4203:                             P8XH (Zero, 0xB9)

Error    4084 -           Object does not exist ^  (P8XH)

dsdt2.dsl   4230:                         P8XH (Zero, 0xC0)

Error    4084 -       Object does not exist ^  (P8XH)

dsdt2.dsl   4419:                         Method (WQAA, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAA)

dsdt2.dsl   4626:                         Method (WQAB, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAB)

dsdt2.dsl   4653:                         Method (WQAC, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAC)

dsdt2.dsl   4674:                         Method (WQAD, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAD)

dsdt2.dsl   4773:                         Method (WQAE, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAE)

dsdt2.dsl   4860:                         Method (WQAF, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAF)

dsdt2.dsl   4977:                         Method (WQAG, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAG)

dsdt2.dsl   5088:                         Method (WQAH, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAH)

dsdt2.dsl   5217:                         Method (WQAI, 1, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WQAI)

dsdt2.dsl   5269:                         Method (WSAA, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAA)

dsdt2.dsl   5476:                         Method (WSAB, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAB)

dsdt2.dsl   5503:                         Method (WSAC, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAC)

dsdt2.dsl   5524:                         Method (WSAD, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAD)

dsdt2.dsl   5623:                         Method (WSAE, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAE)

dsdt2.dsl   5710:                         Method (WSAF, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAF)

dsdt2.dsl   5827:                         Method (WSAG, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAG)

dsdt2.dsl   5938:                         Method (WSAH, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAH)

dsdt2.dsl   6067:                         Method (WSAI, 2, NotSerialized)

Warning  1114 -                                     ^ Not all control paths return a value (WSAI)

dsdt2.dsl   6407:                     Name (_T_1, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_1)

dsdt2.dsl   6408:                     Name (_T_0, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_0)

dsdt2.dsl   6426:                                         If (LTRE)

Error    4084 -                           Object does not exist ^  (LTRE)

dsdt2.dsl   6431:                                         If (OBFF)

Error    4084 -                           Object does not exist ^  (OBFF)

dsdt2.dsl   6449:                                             If (OBFF)

Error    4084 -                               Object does not exist ^  (OBFF)

dsdt2.dsl   6473:                                                 If (LTRE)

Error    4084 -                                   Object does not exist ^  (LTRE)

dsdt2.dsl   6523:                         Return (GPRW (0x09, 0x04))

Error    4084 -               Object does not exist ^  (GPRW)

dsdt2.dsl   6562:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   6644:                     Name (_T_1, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_1)

dsdt2.dsl   6645:                     Name (_T_0, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_0)

dsdt2.dsl   6663:                                         If (LTRE)

Error    4084 -                           Object does not exist ^  (LTRE)

dsdt2.dsl   6668:                                         If (OBFF)

Error    4084 -                           Object does not exist ^  (OBFF)

dsdt2.dsl   6686:                                             If (OBFF)

Error    4084 -                               Object does not exist ^  (OBFF)

dsdt2.dsl   6710:                                                 If (LTRE)

Error    4084 -                                   Object does not exist ^  (LTRE)

dsdt2.dsl   6760:                         Return (GPRW (0x09, 0x04))

Error    4084 -               Object does not exist ^  (GPRW)

dsdt2.dsl   6799:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   6881:                     Name (_T_1, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_1)

dsdt2.dsl   6882:                     Name (_T_0, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_0)

dsdt2.dsl   6900:                                         If (LTRE)

Error    4084 -                           Object does not exist ^  (LTRE)

dsdt2.dsl   6905:                                         If (OBFF)

Error    4084 -                           Object does not exist ^  (OBFF)

dsdt2.dsl   6923:                                             If (OBFF)

Error    4084 -                               Object does not exist ^  (OBFF)

dsdt2.dsl   6947:                                                 If (LTRE)

Error    4084 -                                   Object does not exist ^  (LTRE)

dsdt2.dsl   6997:                         Return (GPRW (0x09, 0x04))

Error    4084 -               Object does not exist ^  (GPRW)

dsdt2.dsl   7036:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   7118:                     Name (_T_1, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_1)

dsdt2.dsl   7119:                     Name (_T_0, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_0)

dsdt2.dsl   7137:                                         If (LTRE)

Error    4084 -                           Object does not exist ^  (LTRE)

dsdt2.dsl   7142:                                         If (OBFF)

Error    4084 -                           Object does not exist ^  (OBFF)

dsdt2.dsl   7160:                                             If (OBFF)

Error    4084 -                               Object does not exist ^  (OBFF)

dsdt2.dsl   7184:                                                 If (LTRE)

Error    4084 -                                   Object does not exist ^  (LTRE)

dsdt2.dsl   7234:                         Return (GPRW (0x09, 0x04))

Error    4084 -               Object does not exist ^  (GPRW)

dsdt2.dsl   7273:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   7355:                     Name (_T_1, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_1)

dsdt2.dsl   7356:                     Name (_T_0, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_0)

dsdt2.dsl   7374:                                         If (LTRE)

Error    4084 -                           Object does not exist ^  (LTRE)

dsdt2.dsl   7379:                                         If (OBFF)

Error    4084 -                           Object does not exist ^  (OBFF)

dsdt2.dsl   7397:                                             If (OBFF)

Error    4084 -                               Object does not exist ^  (OBFF)

dsdt2.dsl   7421:                                                 If (LTRE)

Error    4084 -                                   Object does not exist ^  (LTRE)

dsdt2.dsl   7471:                         Return (GPRW (0x09, 0x04))

Error    4084 -               Object does not exist ^  (GPRW)

dsdt2.dsl   7510:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   7592:                     Name (_T_1, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_1)

dsdt2.dsl   7593:                     Name (_T_0, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_0)

dsdt2.dsl   7611:                                         If (LTRE)

Error    4084 -                           Object does not exist ^  (LTRE)

dsdt2.dsl   7616:                                         If (OBFF)

Error    4084 -                           Object does not exist ^  (OBFF)

dsdt2.dsl   7634:                                             If (OBFF)

Error    4084 -                               Object does not exist ^  (OBFF)

dsdt2.dsl   7658:                                                 If (LTRE)

Error    4084 -                                   Object does not exist ^  (LTRE)

dsdt2.dsl   7708:                         Return (GPRW (0x09, 0x04))

Error    4084 -               Object does not exist ^  (GPRW)

dsdt2.dsl   7747:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   7829:                     Name (_T_1, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_1)

dsdt2.dsl   7830:                     Name (_T_0, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_0)

dsdt2.dsl   7848:                                         If (LTRE)

Error    4084 -                           Object does not exist ^  (LTRE)

dsdt2.dsl   7853:                                         If (OBFF)

Error    4084 -                           Object does not exist ^  (OBFF)

dsdt2.dsl   7871:                                             If (OBFF)

Error    4084 -                               Object does not exist ^  (OBFF)

dsdt2.dsl   7895:                                                 If (LTRE)

Error    4084 -                                   Object does not exist ^  (LTRE)

dsdt2.dsl   7945:                         Return (GPRW (0x09, 0x04))

Error    4084 -               Object does not exist ^  (GPRW)

dsdt2.dsl   7984:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   8066:                     Name (_T_1, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_1)

dsdt2.dsl   8067:                     Name (_T_0, Zero)  

Remark   5011 - Use of compiler reserved name ^  (_T_0)

dsdt2.dsl   8085:                                         If (LTRE)

Error    4084 -                           Object does not exist ^  (LTRE)

dsdt2.dsl   8090:                                         If (OBFF)

Error    4084 -                           Object does not exist ^  (OBFF)

dsdt2.dsl   8108:                                             If (OBFF)

Error    4084 -                               Object does not exist ^  (OBFF)

dsdt2.dsl   8132:                                                 If (LTRE)

Error    4084 -                                   Object does not exist ^  (LTRE)

dsdt2.dsl   8182:                         Return (GPRW (0x09, 0x04))

Error    4084 -               Object does not exist ^  (GPRW)

dsdt2.dsl   8221:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   8235:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   8249:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   8263:                     If (PICM)

Error    4084 -       Object does not exist ^  (PICM)

dsdt2.dsl   8500:         Method (RDGI, 1, NotSerialized)

Warning  1114 -                     ^ Not all control paths return a value (RDGI)

dsdt2.dsl   8517:         Method (RDGP, 1, NotSerialized)

Warning  1114 -                     ^ Not all control paths return a value (RDGP)

dsdt2.dsl  11379:                     }

Error    4124 -                      ^ syntax error, unexpected '}', expecting '('

dsdt2.dsl  13248:                     }

Error    4124 -                      ^ syntax error, unexpected '}', expecting '('

dsdt2.dsl  14469:             Arg0

Error    4124 -                 ^ syntax error, unexpected PARSEOP_ARG0

dsdt2.dsl  16080:     If (SS1)

Error    4124 -       ^ syntax error, unexpected PARSEOP_IF

dsdt2.dsl  16091:     If (SS3)

Error    4124 -       ^ syntax error, unexpected PARSEOP_IF

dsdt2.dsl  16124:             \_SB.PCI0.LPCB.SPTS (Arg0)

Error    4084 -          Object does not exist ^  (\_SB.PCI0.LPCB.SPTS)

dsdt2.dsl  16125:             \_SB.PCI0.NPTS (Arg0)

Error    4084 -     Object does not exist ^  (\_SB.PCI0.NPTS)

dsdt2.dsl  16131:         \_SB.PCI0.LPCB.SWAK (Arg0)

Error    4084 -      Object does not exist ^  (\_SB.PCI0.LPCB.SWAK)

dsdt2.dsl  16132:         \_SB.PCI0.NWAK (Arg0)

Error    4084 - Object does not exist ^  (\_SB.PCI0.NWAK)

ASL Input:     dsdt2.dsl - 16145 lines, 534494 bytes, 6834 keywords

Hex Dump:      dsdt2.hex - 247669 bytes

Compilation complete. 96 Errors, 20 Warnings, 16 Remarks, 44 Optimizations
```

Yeah, that blew up alright.

I have yet to check in more detail, but it seems that the errors are legitimate. The first one, referring to PICM not existing, is true since PICM isn't define ANYWHERE in the decompiled code, not even as an external variable or method. Maybe it's in another table? It certainly isn't defined in this code.

For "fun," I did this on my desktop also, a Gigabyte board running Gentoo, and I was able to decompile and recompile the code without any problems. So, thus far it seems that the MSI engineers that wrote this thing... may not have done that great of a job. Granted, I still have a lot of testing to do, as well as reading up on ASL syntax and proper programming practices for this environment.

As a curiosity, there are quite a few references to Windows in the decompilation, and actually there is one reference to Linux as well. Something related to OSI, possibly related to the Firmware Bug the kernel is complaining about.

I'll leave this like this for now. If anyone is interested in helping out, or wants to see any of the files I'm working with, let me know and I'll post them up somewhere.

----------

## eyoung100

See these 2 topics for help with Optimus:

Optirun, bumblebee & X failures  :Sad: [Solved]No device detected while startx?

----------

## gemarcano

As an update, I've been in communication with MSI. They whined that they don't support Linux, but then I reproduced the problems in Windows too. I did find out that the Windows binaries (and the Linux binaries built from the newest sources) seem to produce better decompilations of the ACPI tables (less errors and these can be fixed). I still ran into bugs using acpiexec and acpinames. The results of that testing (on Linux it's the same result with the new binaries) is found here. To be honest, I don't know exactly what the errors these two tools report, or even if these errors make sense or if they should be there. My gut tells me that there should not be any errors. Anybody know if this is correct?

In terms of power management, I traced the problem to Nouveau. Once I switched to the Nvidia blob and configure Optimus and Primus, the laptop is now running much cooler and for much longer. Nouveau seems to be crashing itself and then preventing bbswitch from shutting off the graphics card. I'm sad that I'll have to leave Nouveau for some time, but I need the battery life.

I'm waiting for MSI to reply to my report from Windows. They claimed at one point that the Intel ACPI tools were Linux specific. Right, except that their tables were compiled with an Intel compiler, based on the table's headers. We'll see what happens.

----------

