Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
Re: acpibat remaining capacity is 0
To:
Peter Toth <peter.toth198@gmail.com>
Cc:
tech@openbsd.org
Date:
Tue, 18 Mar 2025 11:30:40 +0100

Download raw body.

Thread
> From: Peter Toth <peter.toth198@gmail.com>
> Date: Tue, 18 Mar 2025 08:49:25 +0100

Hi Peter,

Good find!  The issue is indeed the following AML operation:

    Divide (Local3, 0x64, Local3, Local0)

The 3rd and 4th argument here are where the remainder and result are
stored.  But the code stores the remainder in the same variable as the
original dividend.  But changing the order in which the remainder and
result are calculated and stored won't fix the bug.  With your diff:

    Divide (Local3, 0x64, Local0, Local3)
   
would fail instead.

So here is a better fix.  Can you confirm that this fixes the issue
too?


Index: dev/acpi/dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
diff -u -p -r1.273 dsdt.c
--- dev/acpi/dsdt.c	23 Jan 2025 13:40:26 -0000	1.273
+++ dev/acpi/dsdt.c	18 Mar 2025 10:24:51 -0000
@@ -3819,7 +3819,7 @@ aml_parse(struct aml_scope *scope, int r
 	struct aml_scope *mscope, *iscope;
 	uint8_t *start, *end;
 	const char *ch;
-	int64_t ival;
+	int64_t ival, rem;
 	struct timespec ts;
 
 	my_ret = NULL;
@@ -4036,12 +4036,11 @@ aml_parse(struct aml_scope *scope, int r
 			my_ret = aml_seterror(scope, "Divide by Zero!");
 			break;
 		}
-		ival = aml_evalexpr(opargs[0]->v_integer,
+		rem = aml_evalexpr(opargs[0]->v_integer,
 		    opargs[1]->v_integer, AMLOP_MOD);
-		aml_store(scope, opargs[2], ival, NULL);
-
 		ival = aml_evalexpr(opargs[0]->v_integer,
 		    opargs[1]->v_integer, AMLOP_DIVIDE);
+		aml_store(scope, opargs[2], rem, NULL);
 		aml_store(scope, opargs[3], ival, NULL);
 		break;
 	case AMLOP_NOT: