Subject: ACPI address32 resource support
To: NetBSD current <current-users@netbsd.org>
From: Nicolas Joly <njoly@pasteur.fr>
List: current-users
Date: 09/24/2007 12:17:13
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Hi,

I recently found that some hpet@acpi devices do not attach correctly
because of missing ACPI address32 resource support.

By example, on a Dell Poweredge 860 :

 hpet0 at acpi0 (HPET, PNP0103-0)
 hpet0: unable to find mem register resource

I tracked this to our ACPI resource parsing which do not support
address32 (= DWord Address Space Descriptor).

sys/dev/acpi/acpi_resource.c:
        case ACPI_RESOURCE_TYPE_ADDRESS32:
                ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
                                     "Address32 unimplemented\n"));
                break;

And the device require it:
    Device(HPET) {
        Name(_HID, 0x0301d041)
        Name(_UID, 0x0)
        Name(_STA, 0xb)
        Name(_CRS, Buffer(0x1c) {0x87, 0x17, 0x0, 0x0, 0xd, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0xfe, 0xff, 0x3, 0xd0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x79, 0x0
        /* ResourceTemplate() {
         0x0000  DWordMemory(ResourceConsumer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, 0x0, 0xfed00000, 0xfed003ff, 0x0, 0x400, 121, '', AddressRangeMemory, TypeStatic)
        } */
         })
    }

The attached patch fix it by addind ACPI address32 resource support
(fixed size only).

hpet0 at acpi0 (HPET, PNP0103-0)
hpet0: mem 0xfed00000-0xfed003ff
hpet0: Found 64-bits HPET, will only use lowest 32-bits
timecounter: Timecounter "hpet0" frequency 14318179 Hz quality 2000

I'd like to to commit it, but want some review from an ACPI guru
before.

Thanks.

NB: While here, i fixed some other small things (missing break,
    incorrect debug message, ...).

-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.

--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="netbsd-acpiresource.diff"

Index: sys/dev/acpi/acpi_resource.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpi_resource.c,v
retrieving revision 1.21
diff -u -r1.21 acpi_resource.c
--- sys/dev/acpi/acpi_resource.c	16 Nov 2006 01:32:47 -0000	1.21
+++ sys/dev/acpi/acpi_resource.c	21 Sep 2007 08:00:47 -0000
@@ -113,7 +113,7 @@
 
 	case ACPI_RESOURCE_TYPE_IO:
 		if (res->Data.Io.Minimum ==
-			    res->Data.Io.Maximum) {
+		    res->Data.Io.Maximum) {
 			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
 					     "Io 0x%x/%d\n",
 					     res->Data.Io.Minimum,
@@ -128,7 +128,7 @@
 					     res->Data.Io.Minimum,
 					     res->Data.Io.Maximum,
 					     res->Data.Io.AddressLength));
-			if (ops->ioport)
+			if (ops->iorange)
 				(*ops->iorange)(arg->dev, arg->context,
 				    res->Data.Io.Minimum,
 				    res->Data.Io.Maximum,
@@ -237,10 +237,52 @@
 				     "End dependant functions\n"));
 		if (ops->end_dep)
 			(*ops->end_dep)(arg->dev, arg->context);
+		break;
 
 	case ACPI_RESOURCE_TYPE_ADDRESS32:
-		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
-				     "Address32 unimplemented\n"));
+		/* XXX Only fixed size supported for now */
+		if (res->Data.Address32.AddressLength == 0)
+			break;
+#define ADRRESS32_FIXED2(r)						\
+	((r)->Data.Address32.MinAddressFixed == ACPI_ADDRESS_FIXED &&	\
+	 (r)->Data.Address32.MaxAddressFixed == ACPI_ADDRESS_FIXED)
+		switch (res->Data.Address32.ResourceType) {
+		case ACPI_MEMORY_RANGE:
+			if (ADRRESS32_FIXED2(res)) {
+				if (ops->memory)
+					(*ops->memory)(arg->dev, arg->context,
+					    res->Data.Address32.Minimum,
+					    res->Data.Address32.AddressLength);
+			} else {
+				if (ops->memrange)
+					(*ops->memrange)(arg->dev, arg->context,
+					    res->Data.Address32.Minimum,
+					    res->Data.Address32.Maximum,
+					    res->Data.Address32.AddressLength,
+					    res->Data.Address32.Granularity);
+			}
+			break;
+		case ACPI_IO_RANGE:
+			if (ADRRESS32_FIXED2(res)) {
+				if (ops->ioport)
+					(*ops->ioport)(arg->dev, arg->context,
+					    res->Data.Address32.Minimum,
+					    res->Data.Address32.AddressLength);
+			} else {
+				if (ops->iorange)
+					(*ops->iorange)(arg->dev, arg->context,
+					    res->Data.Address32.Minimum,
+					    res->Data.Address32.Maximum,
+					    res->Data.Address32.AddressLength,
+					    res->Data.Address32.Granularity);
+			}
+			break;
+		case ACPI_BUS_NUMBER_RANGE:
+			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
+				      "Address32/BusNumber unimplemented\n"));
+			break;
+		}
+#undef ADRRESS32_FIXED2
 		break;
 
 	case ACPI_RESOURCE_TYPE_ADDRESS16:
@@ -260,7 +302,7 @@
 
 	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
-				     "ExtendedIrq unimplemented\n"));
+				     "GenericRegister unimplemented\n"));
 		break;
 
 	case ACPI_RESOURCE_TYPE_VENDOR:

--uAKRQypu60I7Lcqm--