Mark Kettenis <mark.kette...@xs4all.nl> writes: > As diagnosed by some other people (armani@, jcs@?) a while ago, our > code to deal with IndexField() operators in our AML interpreter is > quite broken. It works for fields that are less than a byte in size, > but anything else is pretty much completely busted. I wouldn't be > surprised if this is the cause of many ACPI-related problems. One > that comes to mind are the ridiculous temperatures reported by > acpitz(4) that have been plaguing us since basically forever. > > I don't have a lot of machines that have AML with IndexField() > operators. I've verified that those return the correct values, but > this defenitely could use further testing on a wide variety of > i386/amd64 hardware please. > > > Index: dsdt.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v > retrieving revision 1.200 > diff -u -p -r1.200 dsdt.c > --- dsdt.c 10 Apr 2013 01:35:55 -0000 1.200 > +++ dsdt.c 20 May 2013 16:55:27 -0000 > @@ -2221,8 +2221,9 @@ aml_evalhid(struct aml_node *node, struc > return (0); > } > > -void aml_rwfield(struct aml_value *, int, int, struct aml_value *, int); > void aml_rwgas(struct aml_value *, 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 > @@ -2341,6 +2342,81 @@ aml_rwgas(struct aml_value *rgn, int bpo > aml_freevalue(&tmp); > } > > + > +void > +aml_rwindexfield(struct aml_value *fld, struct aml_value *val, int mode) > +{ > + struct aml_value tmp, *ref1, *ref2; > + void *tbit, *vbit; > + int vpos, bpos, blen; > + int indexval; > + int sz, len; > + > + ref2 = fld->v_field.ref2; > + ref1 = fld->v_field.ref1; > + bpos = fld->v_field.bitpos; > + blen = fld->v_field.bitlen; > + > + memset(&tmp, 0, sizeof(tmp)); > + tmp.refcnt = 99; > + > + /* Get field access size */ > + switch (AML_FIELD_ACCESS(fld->v_field.flags)) { > + case AML_FIELD_WORDACC: > + sz = 2; > + break; > + case AML_FIELD_DWORDACC: > + sz = 4; > + break; > + case AML_FIELD_QWORDACC: > + sz = 8; > + break; > + default: > + sz = 1; > + break; > + } > + > + if (blen > aml_intlen) { > + if (mode == ACPI_IOREAD) { > + /* Read from a large field: create buffer */ > + _aml_setvalue(val, AML_OBJTYPE_BUFFER, > + (blen + 7) << 3, 0); > + } > + vbit = val->v_buffer; > + } else { > + if (mode == ACPI_IOREAD) { > + /* Read from a short field: initialize integer */ > + _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0); > + } > + vbit = &val->v_integer; > + } > + tbit = &tmp.v_integer; > + vpos = 0; > + > + indexval = (bpos >> 3) & ~(sz - 1); > + bpos = bpos - (indexval << 3); > + > + while (blen > 0) { > + len = min(blen, (sz << 3) - bpos); > + > + /* Write index register */ > + _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, indexval, 0); > + aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE); > + indexval += sz; > + > + /* Read/write data register */ > + _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, 0, 0); > + if (mode == ACPI_IOWRITE) > + aml_bufcpy(tbit, 0, vbit, vpos, len); > + aml_rwfield(ref1, bpos, len, &tmp, mode); > + if (mode == ACPI_IOREAD) > + aml_bufcpy(vbit, vpos, tbit, 0, len); > + vpos += len; > + blen -= len; > + bpos = 0; > + } > +} > + > void > aml_rwfield(struct aml_value *fld, int bpos, int blen, struct aml_value *val, > int mode) > @@ -2356,10 +2432,7 @@ aml_rwfield(struct aml_value *fld, int b > memset(&tmp, 0, sizeof(tmp)); > aml_addref(&tmp, "fld.write"); > if (fld->v_field.type == AMLOP_INDEXFIELD) { > - _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, fld->v_field.ref3, 0); > - aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE); > - aml_rwfield(ref1, fld->v_field.bitpos, fld->v_field.bitlen, > - val, mode); > + aml_rwindexfield(fld, val, mode); > } else if (fld->v_field.type == AMLOP_BANKFIELD) { > _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, fld->v_field.ref3, 0); > aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE); > @@ -2414,10 +2487,6 @@ aml_createfield(struct aml_value *field, > opcode == AMLOP_BANKFIELD) ? > AML_OBJTYPE_FIELDUNIT : > AML_OBJTYPE_BUFFERFIELD; > - if (opcode == AMLOP_INDEXFIELD) { > - indexval = bpos >> 3; > - bpos &= 7; > - } > > if (field->type == AML_OBJTYPE_BUFFERFIELD && > data->type != AML_OBJTYPE_BUFFER)
Anything specific to test with the diff? So far I haven't noticed any regressions running this diff on Thinkpad X201. timo OpenBSD 5.3-current (GENERIC.MP) #4: Mon May 20 21:57:08 EEST 2013 r...@mandrake.wickedbsd.net:/usr/src/sys/arch/amd64/compile/GENERIC.MP real mem = 8357658624 (7970MB) avail mem = 8127467520 (7750MB) mainbus0 at root bios0 at mainbus0: SMBIOS rev. 2.6 @ 0xe0010 (78 entries) bios0: vendor LENOVO version "6QET69WW (1.39 )" date 04/26/2012 bios0: LENOVO 32492EU acpi0 at bios0: rev 2 acpi0: sleep states S0 S3 S4 S5 acpi0: tables DSDT FACP SSDT ECDT APIC MCFG HPET ASF! SLIC BOOT SSDT TCPA DMAR SSDT SSDT SSDT acpi0: wakeup devices LID_(S3) SLPB(S3) IGBE(S4) EXP1(S4) EXP2(S4) EXP3(S4) EXP4(S4) EXP5(S4) EHC1(S3) EHC2(S3) HDEF(S4) acpitimer0 at acpi0: 3579545 Hz, 24 bits acpiec0 at acpi0 acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat cpu0 at mainbus0: apid 0 (boot processor) cpu0: Intel(R) Core(TM) i5 CPU M 540 @ 2.53GHz, 2793.53 MHz cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,AES,NXE,LONG,LAHF,PERF,ITSC cpu0: 256KB 64b/line 8-way L2 cache cpu0: apic clock running at 133MHz cpu1 at mainbus0: apid 1 (application processor) cpu1: Intel(R) Core(TM) i5 CPU M 540 @ 2.53GHz, 2793.00 MHz cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,AES,NXE,LONG,LAHF,PERF,ITSC cpu1: 256KB 64b/line 8-way L2 cache cpu2 at mainbus0: apid 4 (application processor) cpu2: Intel(R) Core(TM) i5 CPU M 540 @ 2.53GHz, 2793.00 MHz cpu2: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,AES,NXE,LONG,LAHF,PERF,ITSC cpu2: 256KB 64b/line 8-way L2 cache cpu3 at mainbus0: apid 5 (application processor) cpu3: Intel(R) Core(TM) i5 CPU M 540 @ 2.53GHz, 2793.00 MHz cpu3: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,AES,NXE,LONG,LAHF,PERF,ITSC cpu3: 256KB 64b/line 8-way L2 cache ioapic0 at mainbus0: apid 1 pa 0xfec00000, version 20, 24 pins ioapic0: misconfigured as apic 2, remapped to apid 1 acpimcfg0 at acpi0 addr 0xe0000000, bus 0-255 acpihpet0 at acpi0: 14318179 Hz acpiprt0 at acpi0: bus 0 (PCI0) acpiprt1 at acpi0: bus -1 (PEG_) acpiprt2 at acpi0: bus 13 (EXP1) acpiprt3 at acpi0: bus -1 (EXP2) acpiprt4 at acpi0: bus -1 (EXP3) acpiprt5 at acpi0: bus 5 (EXP4) acpiprt6 at acpi0: bus 2 (EXP5) acpicpu0 at acpi0: C3, C1, PSS acpicpu1 at acpi0: C3, C1, PSS acpicpu2 at acpi0: C3, C1, PSS acpicpu3 at acpi0: C3, C1, PSS acpipwrres0 at acpi0: PUBS acpitz0 at acpi0: critical temperature is 100 degC acpibtn0 at acpi0: LID_ acpibtn1 at acpi0: SLPB acpibat0 at acpi0: BAT0 model "42T4650" serial 8908 type LION oem "Panasonic" acpibat1 at acpi0: BAT1 not present acpiac0 at acpi0: AC unit online acpithinkpad0 at acpi0 acpidock0 at acpi0: GDCK not docked (0) cpu0: Enhanced SpeedStep 2793 MHz: speeds: 2534, 2533, 2399, 2266, 2133, 1999, 1866, 1733, 1599, 1466, 1333, 1199 MHz pci0 at mainbus0 bus 0 pchb0 at pci0 dev 0 function 0 "Intel Core Host" rev 0x02 vga1 at pci0 dev 2 function 0 "Intel HD Graphics" rev 0x02 intagp0 at vga1 agp0 at intagp0: aperture at 0xd0000000, size 0x10000000 inteldrm0 at vga1 drm0 at inteldrm0 inteldrm0: 1280x800 wsdisplay0 at vga1 mux 1: console (std, vt100 emulation) wsdisplay0: screen 1-5 added (std, vt100 emulation) "Intel 3400 MEI" rev 0x06 at pci0 dev 22 function 0 not configured "Intel 3400 KT" rev 0x06 at pci0 dev 22 function 3 not configured em0 at pci0 dev 25 function 0 "Intel 82577LM" rev 0x06: msi, address 00:26:2d:f1:da:75 ehci0 at pci0 dev 26 function 0 "Intel 3400 USB" rev 0x06: apic 1 int 23 usb0 at ehci0: USB revision 2.0 uhub0 at usb0 "Intel EHCI root hub" rev 2.00/1.00 addr 1 azalia0 at pci0 dev 27 function 0 "Intel 3400 HD Audio" rev 0x06: msi azalia0: codecs: Conexant/0x5069, Intel/0x2804, using Conexant/0x5069 audio0 at azalia0 ppb0 at pci0 dev 28 function 0 "Intel 3400 PCIE" rev 0x06: msi pci1 at ppb0 bus 13 ppb1 at pci0 dev 28 function 3 "Intel 3400 PCIE" rev 0x06: msi pci2 at ppb1 bus 5 ppb2 at pci0 dev 28 function 4 "Intel 3400 PCIE" rev 0x06: msi pci3 at ppb2 bus 2 iwn0 at pci3 dev 0 function 0 "Intel Centrino Advanced-N 6200" rev 0x35: msi, MIMO 2T2R, MoW, address 00:23:14:23:6e:18 ehci1 at pci0 dev 29 function 0 "Intel 3400 USB" rev 0x06: apic 1 int 19 usb1 at ehci1: USB revision 2.0 uhub1 at usb1 "Intel EHCI root hub" rev 2.00/1.00 addr 1 ppb3 at pci0 dev 30 function 0 "Intel 82801BAM Hub-to-PCI" rev 0xa6 pci4 at ppb3 bus 14 pcib0 at pci0 dev 31 function 0 "Intel QM57 LPC" rev 0x06 ahci0 at pci0 dev 31 function 2 "Intel 3400 AHCI" rev 0x06: msi, AHCI 1.3 ahci0: device on port 0 didn't come ready, TFD: 0x80<BSY> ahci0: CLO did not complete scsibus0 at ahci0: 32 targets sd0 at scsibus0 targ 0 lun 0: <ATA, INTEL SSDSA2M160, 2CV1> SCSI3 0/direct fixed naa.5001517959106b36 sd0: 152627MB, 512 bytes/sector, 312581808 sectors, thin ichiic0 at pci0 dev 31 function 3 "Intel 3400 SMBus" rev 0x06: apic 1 int 23 iic0 at ichiic0 spdmem0 at iic0 addr 0x50: 4GB DDR3 SDRAM PC3-10600 SO-DIMM spdmem1 at iic0 addr 0x51: 4GB DDR3 SDRAM PC3-10600 SO-DIMM itherm0 at pci0 dev 31 function 6 "Intel 3400 Thermal" rev 0x06 isa0 at pcib0 isadma0 at isa0 pckbc0 at isa0 port 0x60/5 pckbd0 at pckbc0 (kbd slot) pckbc0: using irq 1 for kbd slot wskbd0 at pckbd0: console keyboard, using wsdisplay0 pms0 at pckbc0 (aux slot #0) pckbc0: using irq 12 for aux slot #0 wsmouse0 at pms0 mux 0 pcppi0 at isa0 port 0x61 spkr0 at pcppi0 aps0 at isa0 port 0x1600/31 pci5 at mainbus0 bus 255 pchb1 at pci5 dev 0 function 0 vendor "Intel", unknown product 0x2c62 rev 0x02 pchb2 at pci5 dev 0 function 1 vendor "Intel", unknown product 0x2d01 rev 0x02 pchb3 at pci5 dev 2 function 0 vendor "Intel", unknown product 0x2d10 rev 0x02 pchb4 at pci5 dev 2 function 1 vendor "Intel", unknown product 0x2d11 rev 0x02 pchb5 at pci5 dev 2 function 2 vendor "Intel", unknown product 0x2d12 rev 0x02 pchb6 at pci5 dev 2 function 3 vendor "Intel", unknown product 0x2d13 rev 0x02 mtrr: Pentium Pro MTRR support uhub2 at uhub0 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 ugen0 at uhub2 port 3 "UPEK Biometric Coprocessor" rev 1.01/0.02 addr 3 ugen1 at uhub2 port 4 "Broadcom Corp Broadcom Bluetooth Device" rev 2.00/3.60 addr 4 uhub3 at uhub1 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 vscsi0 at root scsibus1 at vscsi0: 256 targets softraid0 at root scsibus2 at softraid0: 256 targets sd1 at scsibus2 targ 1 lun 0: <OPENBSD, SR CRYPTO, 005> SCSI2 0/direct fixed sd1: 152625MB, 512 bytes/sector, 312576113 sectors root on sd1a (741cf65615793b8b.a) swap on sd1b dump on sd1b ugen0 detached ugen1 detached uhub2 detached uhub2 at uhub0 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 ugen0 at uhub2 port 3 "UPEK Biometric Coprocessor" rev 1.01/0.02 addr 3 ugen1 at uhub2 port 4 "Broadcom Corp Broadcom Bluetooth Device" rev 2.00/3.60 addr 4 uhub3 detached uhub3 at uhub1 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 ugen0 detached ugen1 detached uhub2 detached uhub2 at uhub0 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 ugen0 at uhub2 port 3 "UPEK Biometric Coprocessor" rev 1.01/0.02 addr 3 ugen1 at uhub2 port 4 "Broadcom Corp Broadcom Bluetooth Device" rev 2.00/3.60 addr 4 uhub3 detached uhub3 at uhub1 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 ugen0 detached ugen1 detached uhub2 detached uhub2 at uhub0 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 ugen0 at uhub2 port 3 "UPEK Biometric Coprocessor" rev 1.01/0.02 addr 3 ugen1 at uhub2 port 4 "Broadcom Corp Broadcom Bluetooth Device" rev 2.00/3.60 addr 4 uhub3 detached uhub3 at uhub1 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2