Download raw body.
[patch] Re: acpi: panic in aml_convert() on 2025 Framework Laptop 13
With the attached patch, the machine boots. :)
Installer works. X works. I'll send a separate email to dmesg@ with more
details.
Sven M. Hallberg on Fri, Jun 06 2025:
> Attempting to boot on the recent Framework Laptop 13 with AMD Ryzen AI
> 300 series processor leads to a panic with the following message:
>
> Could not convert 1 to 5
>
> panic: aml_die aml_convert:2094
>
> The source is in /sys/dev/acpi/dsdt.c (line 2094). Some investigation
> shows that aml_compare() is trying to convert an AML_OBJTYPE_INTEGER (1)
> to AML_OBJTYPE_FIELDUNIT (5) while handling an AMLOP_LEQUAL in
> aml_parse(). This conversion case is not implemented.
>
> The implementation of AMLOP_CONCAT in aml_concat() has the same issue
> and implicit conversions might be missing in other cases (see
> explanations below). The arithmetic operators, for instance, seem to
> require their arguments to be integers without a call to aml_convert().
>
> [...]
>
> For type Field Unit, Table 19.6 lists all possible conversions.
> Technically, any missing cases should be added to aml_convert().
> To fix this particular case, at least the conversion from Field Unit
> to Integer must be implemented.
>
> All the arithmetic comparison operators accept integer, string, or
> buffer arguments. The aml_compare() function should try to convert the
> first operand to these types in order, before the existing call to
> aml_convert() for the second operand. Similar for aml_concat().
Index: dev/acpi/dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.274
diff -u -p -r1.274 dsdt.c
--- dev/acpi/dsdt.c 22 Mar 2025 18:14:37 -0000 1.274
+++ dev/acpi/dsdt.c 6 Jun 2025 22:16:44 -0000
@@ -1753,6 +1753,7 @@ struct aml_scope *aml_pushscope(struct a
struct aml_scope *aml_popscope(struct aml_scope *);
void aml_showstack(struct aml_scope *);
+struct aml_value *aml_tryconv(struct aml_value *, int, int);
struct aml_value *aml_convert(struct aml_value *, int, int);
int aml_matchtest(int64_t, int64_t, int);
@@ -1766,6 +1767,8 @@ int aml_ccrlen(int, union acpi_resource
void aml_store(struct aml_scope *, struct aml_value *, int64_t,
struct aml_value *);
+void aml_rwfield(struct aml_value *, int, int, struct aml_value *,
+ int);
/*
* Reference Count functions
@@ -2022,7 +2025,7 @@ aml_hextoint(const char *str)
}
struct aml_value *
-aml_convert(struct aml_value *a, int ctype, int clen)
+aml_tryconv(struct aml_value *a, int ctype, int clen)
{
struct aml_value *c = NULL;
@@ -2045,6 +2048,11 @@ aml_convert(struct aml_value *a, int cty
c = aml_allocvalue(AML_OBJTYPE_BUFFER, a->length,
a->v_string);
break;
+ case AML_OBJTYPE_BUFFERFIELD:
+ case AML_OBJTYPE_FIELDUNIT:
+ c = aml_allocvalue(AML_OBJTYPE_BUFFER, 0, NULL);
+ aml_rwfield(a, 0, a->v_field.bitlen, c, ACPI_IOREAD);
+ break;
}
break;
case AML_OBJTYPE_INTEGER:
@@ -2062,6 +2070,13 @@ aml_convert(struct aml_value *a, int cty
case AML_OBJTYPE_UNINITIALIZED:
c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL);
break;
+ case AML_OBJTYPE_BUFFERFIELD:
+ case AML_OBJTYPE_FIELDUNIT:
+ if (a->v_field.bitlen > aml_intlen)
+ break;
+ c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL);
+ aml_rwfield(a, 0, a->v_field.bitlen, c, ACPI_IOREAD);
+ break;
}
break;
case AML_OBJTYPE_STRING:
@@ -2087,7 +2102,15 @@ aml_convert(struct aml_value *a, int cty
}
break;
}
- if (c == NULL) {
+ return c;
+}
+
+struct aml_value *
+aml_convert(struct aml_value *a, int ctype, int clen)
+{
+ struct aml_value *c;
+
+ if ((c = aml_tryconv(a, ctype, clen)) == NULL) {
#ifndef SMALL_KERNEL
aml_showvalue(a);
#endif
@@ -2099,8 +2122,26 @@ aml_convert(struct aml_value *a, int cty
int
aml_compare(struct aml_value *a1, struct aml_value *a2, int opcode)
{
+ struct aml_value *cv; /* value after conversion */
int rc = 0;
+ /*
+ * Convert A1 to integer, string, or buffer.
+ *
+ * The possible conversions listed in Table 19.6 of the ACPI spec
+ * imply that unless we already got one of the three supported types,
+ * the conversion must be from field unit or buffer field. In both
+ * cases, the rules (Table 19.7) state that we should convert to
+ * integer if possible with buffer as a fallback.
+ */
+ if (a1->type != AML_OBJTYPE_INTEGER && a1->type != AML_OBJTYPE_STRING
+ && a1->type != AML_OBJTYPE_BUFFER) {
+ cv = aml_tryconv(a1, AML_OBJTYPE_INTEGER, -1);
+ if (cv == NULL)
+ cv = aml_convert(a1, AML_OBJTYPE_BUFFER, -1);
+ a1 = cv;
+ }
+
/* Convert A2 to type of A1 */
a2 = aml_convert(a2, a1->type, -1);
if (a1->type == AML_OBJTYPE_INTEGER)
@@ -2127,6 +2168,14 @@ aml_concat(struct aml_value *a1, struct
{
struct aml_value *c = NULL;
+ /*
+ * Make A1 an integer, string, or buffer. Unless we already got one
+ * of these three types, convert to string.
+ */
+ if (a1->type != AML_OBJTYPE_INTEGER && a1->type != AML_OBJTYPE_STRING
+ && a1->type != AML_OBJTYPE_BUFFER)
+ a1 = aml_convert(a1, AML_OBJTYPE_STRING, -1);
+
/* Convert arg2 to type of arg1 */
a2 = aml_convert(a2, a1->type, -1);
switch (a1->type) {
@@ -2292,7 +2341,6 @@ void aml_rwgen(struct aml_value *, int,
void aml_rwgpio(struct aml_value *, int, int, struct aml_value *, int, int);
void aml_rwgsb(struct aml_value *, int, int, int, struct aml_value *, int, int);
void aml_rwindexfield(struct aml_value *, struct aml_value *val, int);
-void aml_rwfield(struct aml_value *, int, int, struct aml_value *, int);
/* Get PCI address for opregion objects */
int
[patch] Re: acpi: panic in aml_convert() on 2025 Framework Laptop 13