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

Reply via email to