Bug 217714

Summary: ACPI Error: No handler for SystemCMOS Operation Region for acpi-tad driver
Product: ACPI Reporter: Ivan Hu (ivan.hu)
Component: OtherAssignee: Zhang Rui (rui.zhang)
Status: NEEDINFO ---    
Severity: normal CC: bagasdotme, jared.chang, kai.heng.feng, max.lee, rui.zhang
Priority: P3    
Hardware: All   
OS: Linux   
Kernel Version: 6.1 Subsystem:
Regression: No Bisected commit-id:
Attachments: PatchL Install SystemCMOS space handler for ACPI000E
patch v2

Description Ivan Hu 2023-07-27 04:34:11 UTC
Get ACPI error mesages below, 

[Wed May 31 14:34:07 2023] ACPI Error: No handler for Region [RTCM] (000000007ecf70cd) [SystemCMOS] (20220331/evregion-130)
[Wed May 31 14:34:07 2023] ACPI Error: Region SystemCMOS (ID=5) has no handler (20220331/exfldio-261)

[Wed May 31 14:34:07 2023] Initialized Local Variables for Method [_GRT]:
[Wed May 31 14:34:07 2023] Local1: 00000000d3a30199 <Obj> Integer 0000000000000000
[Wed May 31 14:34:07 2023] No Arguments are initialized for method [_GRT]
[Wed May 31 14:34:07 2023] ACPI Error: Aborting method \_SB.AWAC._GRT due to previous error (AE_NOT_EXIST) (20220331/psparse-529)

The issue comes from the Bios implement ACPI AWAC(time and alarm device, "ACPI000E") by using the SystemCMOS, and the kernel acpi-tad driver has no handler for dealing with it. When it call _GRT: Get Real Time or _SRT: Set Real Time, so it will get the "No handler for Region SystemCMOS" and AE_NOT_EXIST issue.

        Device (AWAC)
        {
            Name (_HID, "ACPI000E" /* Time and Alarm Device */) 
            Name (WAST, Zero)
            Name (WTTR, Zero)
            ....
            Method (_GCP, 0, NotSerialized) // _GCP: Get Capabilities
            {
                Return (0xB7)
            }

            OperationRegion (RTCM, SystemCMOS, Zero, 0x3F)
            Field (RTCM, ByteAcc, Lock, Preserve)
            {
                SEC, 8,
                Offset (0x02),
                MIN, 8,
                Offset (0x04),
                HOR, 8,
                Offset (0x07),
                DAY, 8,
                MON, 8,
                YEAR, 8,
                REGA, 8,
                Offset (0x32),
                CNTY, 8
            }

            Method (_GRT, 0, Serialized) // _GRT: Get Real Time
            {
                Name (BUFF, Buffer (0x10) {})
                CreateWordField (BUFF, Zero, Y)
                CreateByteField (BUFF, 0x02, M)
                CreateByteField (BUFF, 0x03, D)
                CreateByteField (BUFF, 0x04, H)
                CreateByteField (BUFF, 0x05, MIN1)
                CreateByteField (BUFF, 0x06, S)
                CreateByteField (BUFF, 0x07, V)
                CreateWordField (BUFF, 0x0A, TZ)
                CreateByteField (BUFF, 0x0C, DL)
                Acquire (RTCL, 0xFFFF)
                Local1 = Zero
                Name (TOUT, 0x000186A0)
                TOUT /= 0x0A
                While (((REGA & 0x80) && (Local1 < TOUT)))
                {
                    Stall (0x0A)
                    Local1 += 0x0A
                }

                If ((Local1 >= TOUT))
                {
                    ADBG ("_GRT timeout fail")
                }

                FromBCD (YEAR, Local5)
                FromBCD (CNTY, Local6)
                Y = ((Local6 * 0x64) + Local5)
                FromBCD (MON, M) /* \_SB_.AWAC._GRT.M___ */
                FromBCD (DAY, D) /* \_SB_.AWAC._GRT.D___ */
                FromBCD (HOR, H) /* \_SB_.AWAC._GRT.H___ */
                FromBCD (MIN, MIN1) /* \_SB_.AWAC._GRT.MIN1 */
                FromBCD (SEC, S) /* \_SB_.AWAC._GRT.S___ */
                Release (RTCL)
                TZ = 0x07FF
                DL = Zero
                V = One
                Return (BUFF) /* \_SB_.AWAC._GRT.BUFF */
            }

            Method (_SRT, 1, NotSerialized) // _SRT: Set Real Time
            {
                CreateWordField (Arg0, Zero, Y)
                CreateByteField (Arg0, 0x02, M)
                CreateByteField (Arg0, 0x03, D)
                CreateByteField (Arg0, 0x04, H)
                CreateByteField (Arg0, 0x05, MIN1)
                CreateByteField (Arg0, 0x06, S)
                Acquire (RTCL, 0xFFFF)
                Local1 = Zero
                Name (TOUT, 0x000186A0)
                TOUT /= 0x0A
                While (((REGA & 0x80) && (Local1 < TOUT)))
                {
                    Stall (0x0A)
                    Local1 += 0x0A
                }

                If ((Local1 >= TOUT))
                {
                    ADBG ("_SRT timeout fail")
                    Release (RTCL)
                    Return (0xFFFFFFFF)
                }

                Divide (Y, 0x64, Local5, Local4)
                ToBCD (Local4, CNTY) /* \_SB_.AWAC.CNTY */
                ToBCD (Local5, YEAR) /* \_SB_.AWAC.YEAR */
                ToBCD (M, MON) /* \_SB_.AWAC.MON_ */
                ToBCD (D, DAY) /* \_SB_.AWAC.DAY_ */
                ToBCD (H, HOR) /* \_SB_.AWAC.HOR_ */
                ToBCD (MIN1, MIN) /* \_SB_.AWAC.MIN_ */
                ToBCD (S, SEC) /* \_SB_.AWAC.SEC_ */
                Release (RTCL)
                Return (Zero)
            }
         ...
Comment 1 Bagas Sanjaya 2023-07-27 14:03:10 UTC
(In reply to Ivan Hu from comment #0)
> Get ACPI error mesages below, 
> 
> [Wed May 31 14:34:07 2023] ACPI Error: No handler for Region [RTCM]
> (000000007ecf70cd) [SystemCMOS] (20220331/evregion-130)
> [Wed May 31 14:34:07 2023] ACPI Error: Region SystemCMOS (ID=5) has no
> handler (20220331/exfldio-261)
> 
> [Wed May 31 14:34:07 2023] Initialized Local Variables for Method [_GRT]:
> [Wed May 31 14:34:07 2023] Local1: 00000000d3a30199 <Obj> Integer
> 0000000000000000
> [Wed May 31 14:34:07 2023] No Arguments are initialized for method [_GRT]
> [Wed May 31 14:34:07 2023] ACPI Error: Aborting method \_SB.AWAC._GRT due to
> previous error (AE_NOT_EXIST) (20220331/psparse-529)
> 
> The issue comes from the Bios implement ACPI AWAC(time and alarm device,
> "ACPI000E") by using the SystemCMOS, and the kernel acpi-tad driver has no
> handler for dealing with it. When it call _GRT: Get Real Time or _SRT: Set
> Real Time, so it will get the "No handler for Region SystemCMOS" and
> AE_NOT_EXIST issue.
> 
>         Device (AWAC)
>         {
>             Name (_HID, "ACPI000E" /* Time and Alarm Device */) 
>             Name (WAST, Zero)
>             Name (WTTR, Zero)
>             ....
>             Method (_GCP, 0, NotSerialized) // _GCP: Get Capabilities
>             {
>                 Return (0xB7)
>             }
> 
>             OperationRegion (RTCM, SystemCMOS, Zero, 0x3F)
>             Field (RTCM, ByteAcc, Lock, Preserve)
>             {
>                 SEC, 8,
>                 Offset (0x02),
>                 MIN, 8,
>                 Offset (0x04),
>                 HOR, 8,
>                 Offset (0x07),
>                 DAY, 8,
>                 MON, 8,
>                 YEAR, 8,
>                 REGA, 8,
>                 Offset (0x32),
>                 CNTY, 8
>             }
> 
>             Method (_GRT, 0, Serialized) // _GRT: Get Real Time
>             {
>                 Name (BUFF, Buffer (0x10) {})
>                 CreateWordField (BUFF, Zero, Y)
>                 CreateByteField (BUFF, 0x02, M)
>                 CreateByteField (BUFF, 0x03, D)
>                 CreateByteField (BUFF, 0x04, H)
>                 CreateByteField (BUFF, 0x05, MIN1)
>                 CreateByteField (BUFF, 0x06, S)
>                 CreateByteField (BUFF, 0x07, V)
>                 CreateWordField (BUFF, 0x0A, TZ)
>                 CreateByteField (BUFF, 0x0C, DL)
>                 Acquire (RTCL, 0xFFFF)
>                 Local1 = Zero
>                 Name (TOUT, 0x000186A0)
>                 TOUT /= 0x0A
>                 While (((REGA & 0x80) && (Local1 < TOUT)))
>                 {
>                     Stall (0x0A)
>                     Local1 += 0x0A
>                 }
> 
>                 If ((Local1 >= TOUT))
>                 {
>                     ADBG ("_GRT timeout fail")
>                 }
> 
>                 FromBCD (YEAR, Local5)
>                 FromBCD (CNTY, Local6)
>                 Y = ((Local6 * 0x64) + Local5)
>                 FromBCD (MON, M) /* \_SB_.AWAC._GRT.M___ */
>                 FromBCD (DAY, D) /* \_SB_.AWAC._GRT.D___ */
>                 FromBCD (HOR, H) /* \_SB_.AWAC._GRT.H___ */
>                 FromBCD (MIN, MIN1) /* \_SB_.AWAC._GRT.MIN1 */
>                 FromBCD (SEC, S) /* \_SB_.AWAC._GRT.S___ */
>                 Release (RTCL)
>                 TZ = 0x07FF
>                 DL = Zero
>                 V = One
>                 Return (BUFF) /* \_SB_.AWAC._GRT.BUFF */
>             }
> 
>             Method (_SRT, 1, NotSerialized) // _SRT: Set Real Time
>             {
>                 CreateWordField (Arg0, Zero, Y)
>                 CreateByteField (Arg0, 0x02, M)
>                 CreateByteField (Arg0, 0x03, D)
>                 CreateByteField (Arg0, 0x04, H)
>                 CreateByteField (Arg0, 0x05, MIN1)
>                 CreateByteField (Arg0, 0x06, S)
>                 Acquire (RTCL, 0xFFFF)
>                 Local1 = Zero
>                 Name (TOUT, 0x000186A0)
>                 TOUT /= 0x0A
>                 While (((REGA & 0x80) && (Local1 < TOUT)))
>                 {
>                     Stall (0x0A)
>                     Local1 += 0x0A
>                 }
> 
>                 If ((Local1 >= TOUT))
>                 {
>                     ADBG ("_SRT timeout fail")
>                     Release (RTCL)
>                     Return (0xFFFFFFFF)
>                 }
> 
>                 Divide (Y, 0x64, Local5, Local4)
>                 ToBCD (Local4, CNTY) /* \_SB_.AWAC.CNTY */
>                 ToBCD (Local5, YEAR) /* \_SB_.AWAC.YEAR */
>                 ToBCD (M, MON) /* \_SB_.AWAC.MON_ */
>                 ToBCD (D, DAY) /* \_SB_.AWAC.DAY_ */
>                 ToBCD (H, HOR) /* \_SB_.AWAC.HOR_ */
>                 ToBCD (MIN1, MIN) /* \_SB_.AWAC.MIN_ */
>                 ToBCD (S, SEC) /* \_SB_.AWAC.SEC_ */
>                 Release (RTCL)
>                 Return (Zero)
>             }
>          ...

What kernel version do you have this issue with?
Comment 2 Ivan Hu 2023-07-28 01:15:08 UTC
The kernel base on v6.1.
Comment 3 Zhang Rui 2023-07-28 03:53:29 UTC
Created attachment 304720 [details]
PatchL Install SystemCMOS space handler for ACPI000E

please check if this patch helps.
Comment 4 Max Lee 2023-07-28 15:36:38 UTC
I can confirm the patch on comment 3 , it helps on the issue.

$ cat /sys/devices/platform/ACPI000E\:00/time 
2023:7:28:15:32:5:2047:0

It can get the real time now.
and the dmesg won't exist the CMOS error.
Comment 5 Zhang Rui 2023-07-29 04:14:16 UTC
Created attachment 304725 [details]
patch v2

I have made a few cleanups in the previous patch, and will submit this version for upstream.
Comment 6 Kai-Heng Feng 2023-07-31 01:53:46 UTC
Thanks, please add my tag:

Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>