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

Reply via email to