From owner-acpi-jp@jp.freebsd.org  Fri Oct  5 03:14:37 2001
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id DAA31896;
	Fri, 5 Oct 2001 03:14:37 +0900 (JST)
	(envelope-from owner-acpi-jp@jp.FreeBSD.org)
Received: from tasogare.imasy.or.jp (root@tasogare.imasy.or.jp [202.227.24.5])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id DAA31891
	for <acpi-jp@jp.freebsd.org>; Fri, 5 Oct 2001 03:14:36 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
Received: from localhost (iwasaki.imasy.or.jp [202.227.24.92])
	by tasogare.imasy.or.jp (8.11.6+3.4W/8.11.6/tasogare) with ESMTP/inet id f94IEUm05728
	for <acpi-jp@jp.freebsd.org>; Fri, 5 Oct 2001 03:14:30 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
Date: Fri, 05 Oct 2001 03:14:24 +0900 (JST)
Message-Id: <20011005.031424.30188891.iwasaki@jp.FreeBSD.org>
To: acpi-jp@jp.freebsd.org
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Mailer: Mew version 2.0 on Emacs 20.7 / Mule 4.0 (HANANOEN)
Mime-Version: 1.0
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+010328
X-Sequence: acpi-jp 1333
Subject: [acpi-jp 1333] Accessing IndexField bug?
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

Hi, Intel folks.  I'd like to confirm about accessing IndexField.
When we access to IndexField object, shouldn't we shift and mask the
value from/to IndexField based on offset and bit width in
FieldUnitList of IndexField?

It seems that AcpiExAccessIndexField() is doing read/write operation
against data object of IndexField directly.

My understanding on accessing IndexField is;
Reading: write the position of IndexField to index object,
and read the value from data object,
then extract the target value with adjustment based on offset and width.
Writing: (if Preserve is specified, reading comes first, ie.
write the position of IndexField to index object,
and read the value from data object first 
and update the target bits with adjustment,)
then write position to index and the value back to data object.

I'm not sure if my above understanding is correct, so just would like
to make it clear.

Example is here,

OperationRegion(REG, SystemIO, 0x72, 0x10)
Field(REG, ByteAcc, NoLock, Preserve) {
    IDX,       8,
    DAT,       8
}
IndexField(IDX, DAT, AnyAcc, NoLock, Preserve) {
    Offset(0x20),
    IF1,       1,
    IF2,       2,
    IF4,       4,
}

Method(TEST) {
        /* 0x73:00000000 */
        Store(0x1, IF1)
        /* 0x73:00000001 */
        If(LNot(LEqual(DAT,0x1))) {
                Store("Wrong", DEBUG)
        }

        /* 0x73:00000001 */
        Store(0x2, IF2)
        /* 0x73:00000101 */
        If(LNot(LEqual(DAT,0x5))) {
                Store("Wrong", DEBUG)
        }

        /* 0x73:00000101 */
        Store(0x4, IF4)
        /* 0x73:00100101 */
        If(LNot(LEqual(DAT,0x25))) {
                Store("Wrong", DEBUG)
        }
}

Note that this code is not used on actual machine.  Accessing data
object directly is to verify the written value.  The values in each
comments are expected values of data object.

Here is trace of ACPICA debugger.  Verifications of IF2 and IF4 failed.

% acpicadb test.aml
Parsing Methods:......
6 Control Methods found and parsed (27 nodes total)
ACPI Namespace successfully loaded at root 0x8087534
- debug TEST
Executing \TEST
00000 #0070 [00]  Store
            [00]  (
00001 #000A [01]  ....(UINT8)  0x01,
00003 #002D [01]  ....IF1_  (Path 
            [01]  }

% 
ArgObj:    0x8091b28 <Obj>             Integer 0000000000000001
ArgObj:    0x80916a8 <Node>            Name IF1_ Type-IndxField
00000 #5B80 [00]  OpRegion REG_  (Path \)
            [00]  (
00006 #000A [01]  ....(UINT8)  0x01,
00007 #000A [01]  ....(UINT8)  0x72,
00009 #000A [01]  ....(UINT8)  0x10
            [01]  }

% 
ArgObj:    0x8091ba8 <Obj>             Integer 0000000000000072
ArgObj:    0x8091c28 <Obj>             Integer 0000000000000010
DEBUG[write(1,  8, 0x72)](default: 0x20 / 32) >>
DEBUG[write(1,  8, 0x73)](default: 0x1 / 1) >>
	# XXX here, I think reading first because Preserve is specified.
ResultObj: 0x8091b28 <Obj>             Integer 0000000000000001

0000A #0093 [00]  LEqual
            [00]  (
0000B #002D [01]  ....DAT_,  (Path 
0000F #000A [01]  ....(UINT8)  0x01
            [01]  }

% 
ArgObj:    0x80915a8 <Node>            Name DAT_ Type-RegnField
ArgObj:    0x8091b28 <Obj>             Integer 0000000000000001
DEBUG[read (1,  8, 0x73)](default: 0x1 / 1) >>
ResultObj: 0x8091c28 <Obj>             Integer 00000000FFFFFFFF

00007 #00A0 [00]  If
            [00]  (
00009 #0092 [01]  ....LNot
            [01]  ....(
00000 #0036 [02]  ........[Return Value] Integer 00000000FFFFFFFF
            [02]  ....}
            [01]  }

% 
ArgObj:    0x808f1a8 <Parser>  
ArgObj:    0x8091c28 <Obj>             Integer 00000000FFFFFFFF
ResultObj: 0x8091b28 <Obj>             Integer 0000000000000000

00007 #00A0 [00]  If
Predicate is FALSE, skipping block

% 
0001B #0070 [00]  Store
            [00]  (
0001C #000A [01]  ....(UINT8)  0x02,
0001E #002D [01]  ....IF2_  (Path 
            [01]  }

% 
ArgObj:    0x8091b28 <Obj>             Integer 0000000000000002
ArgObj:    0x80917a8 <Node>            Name IF2_ Type-IndxField
DEBUG[write(1,  8, 0x72)](default: 0x20 / 32) >>
DEBUG[write(1,  8, 0x73)](default: 0x2 / 2) >>
	# XXX value of IF1 were discarded...
ResultObj: 0x8091b28 <Obj>             Integer 0000000000000002

00025 #0093 [00]  LEqual
            [00]  (
00026 #002D [01]  ....DAT_,  (Path 
0002A #000A [01]  ....(UINT8)  0x05
            [01]  }

% 
ArgObj:    0x80915a8 <Node>            Name DAT_ Type-RegnField
ArgObj:    0x8091b28 <Obj>             Integer 0000000000000005
DEBUG[read (1,  8, 0x73)](default: 0x2 / 2) >>
ResultObj: 0x8091ba8 <Obj>             Integer 0000000000000000

00022 #00A0 [00]  If
            [00]  (
00024 #0092 [01]  ....LNot
            [01]  ....(
00000 #0036 [02]  ........[Return Value] Integer 0000000000000000
            [02]  ....}
            [01]  }

% 
ArgObj:    0x808af28 <Parser>  
ArgObj:    0x8091ba8 <Obj>             Integer 0000000000000000
ResultObj: 0x8091b28 <Obj>             Integer 0000000000000001

00022 #00A0 [00]  If
            [00]  (
0002C #0070 [01]  ....Store
            [01]  ....(
0002D #000D [02]  ........"Wrong",
00034 #5B31 [02]  ........Debug
            [02]  ....}
            [01]  }

% 
ArgObj:    0x8091b28 <Obj>             String(5) "Wrong"
ArgObj:    0x8091ba8 [Debug]  
[ACPI Debug] String: Wrong
ResultObj: 0x8091b28 <Obj>             String(5) "Wrong"

00022 #00A0 [00]  If
Predicate was TRUE, executed block

% 
00036 #0070 [00]  Store
            [00]  (
00037 #000A [01]  ....(UINT8)  0x04,
00039 #002D [01]  ....IF4_  (Path 
            [01]  }

% 
ArgObj:    0x8091b28 <Obj>             Integer 0000000000000004
ArgObj:    0x80918a8 <Node>            Name IF4_ Type-IndxField
DEBUG[write(1,  8, 0x72)](default: 0x20 / 32) >>
DEBUG[write(1,  8, 0x73)](default: 0x4 / 4) >>
	# XXX values of IF1 and IF2 were discarded...
ResultObj: 0x8091b28 <Obj>             Integer 0000000000000004

00040 #0093 [00]  LEqual
            [00]  (
00041 #002D [01]  ....DAT_,  (Path 
00045 #000A [01]  ....(UINT8)  0x25
            [01]  }

% 
ArgObj:    0x80915a8 <Node>            Name DAT_ Type-RegnField
ArgObj:    0x8091b28 <Obj>             Integer 0000000000000025
DEBUG[read (1,  8, 0x73)](default: 0x4 / 4) >>
ResultObj: 0x8091c28 <Obj>             Integer 0000000000000000

0003D #00A0 [00]  If
            [00]  (
0003F #0092 [01]  ....LNot
            [01]  ....(
00000 #0036 [02]  ........[Return Value] Integer 0000000000000000
            [02]  ....}
            [01]  }

% 
ArgObj:    0x808f1a8 <Parser>  
ArgObj:    0x8091c28 <Obj>             Integer 0000000000000000
ResultObj: 0x8091b28 <Obj>             Integer 0000000000000001

0003D #00A0 [00]  If
            [00]  (
00047 #0070 [01]  ....Store
            [01]  ....(
00048 #000D [02]  ........"Wrong",
0004F #5B31 [02]  ........Debug
            [02]  ....}
            [01]  }

% 
ArgObj:    0x8091b28 <Obj>             String(5) "Wrong"
ArgObj:    0x8091c28 [Debug]  
[ACPI Debug] String: Wrong
ResultObj: 0x8091b28 <Obj>             String(5) "Wrong"

0003D #00A0 [00]  If
Predicate was TRUE, executed block

% 
- q
 utalloc-0603 [03] UtDumpAllocations     : No outstanding allocations.


Last time we developed own aml interpreter, I think the comparison
behavior between them would be helpful.  Trace attached.

Thanks

% amldb test.aml
Loading test.aml...done
AML>r TEST
Method: Arg 0 From 0x281261e6 To 0x28126237
==== Running TEST. ====
AML>s
[\TEST. START]
Store(0x1, IF1_)
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x0@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x0@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x0](default: 0x0 / 0) >>
[read(1, 0x73)->0x0]
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x20@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_write(1, 1, 0x1, 0x72, 0x8, 0x8)]
	[1:0x0@0x73:0,8]	->[1:0x1@0x73:0,8]
[write(1, 0x1, 0x73)]
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x20@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x1@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x1](default: 0x1 / 1) >>
[read(1, 0x73)->0x1]
AML>
If(LNot(LEqual(DAT_
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x1@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x1](default: 0x1 / 1) >>
[read(1, 0x73)->0x1], 0x1)))
AML>
Store(0x2, IF2_)
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x20@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x1@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x1](default: 0x1 / 1) >>
[read(1, 0x73)->0x1]
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x20@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_write(1, 1, 0x5, 0x72, 0x8, 0x8)]
	[1:0x1@0x73:0,8]	->[1:0x5@0x73:0,8]
[write(1, 0x5, 0x73)]
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x20@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x5@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x5](default: 0x5 / 5) >>
[read(1, 0x73)->0x5]
AML>
If(LNot(LEqual(DAT_
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x5@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x5](default: 0x5 / 5) >>
[read(1, 0x73)->0x5], 0x5)))
AML>
Store(0x4, IF4_)
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x20@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x5@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x5](default: 0x5 / 5) >>
[read(1, 0x73)->0x5]
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x20@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_write(1, 1, 0x25, 0x72, 0x8, 0x8)]
	[1:0x5@0x73:0,8]	->[1:0x25@0x73:0,8]
[write(1, 0x25, 0x73)]
[aml_region_write(1, 1, 0x20, 0x72, 0x0, 0x8)]
	[1:0x20@0x72:0,8]	->[1:0x20@0x72:0,8]
[write(1, 0x20, 0x72)]
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x25@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x25](default: 0x25 / 37) >>
[read(1, 0x73)->0x25]
AML>
If(LNot(LEqual(DAT_
[aml_region_read(1, 1, 0x72, 0x8, 0x8)]
	[1:0x25@0x73:0,8]
DEBUG[read(1, 0x73)&mask:0x25](default: 0x25 / 37) >>
[read(1, 0x73)->0x25], 0x25)))
AML>
[\TEST. END]
TEST  Method: Arg 0 From 0x281261e6 To 0x28126237
NO object
==== TEST finished. ====
AML>

