From owner-acpi-jp@jp.freebsd.org  Sat May 20 16:35:34 2000
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id QAA89271;
	Sat, 20 May 2000 16:35:34 +0900 (JST)
	(envelope-from owner-acpi-jp@jp.FreeBSD.org)
Received: from tasogare.imasy.or.jp (daemon@tasogare.imasy.or.jp [202.227.24.5])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id QAA89266
	for <acpi-jp@jp.freebsd.org>; Sat, 20 May 2000 16:35:34 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
Received: from localhost (isdn10.imasy.or.jp [202.227.24.202])
	by tasogare.imasy.or.jp (8.9.3+3.2W/3.7W-tasogare/smtpfeed 1.04) with ESMTP id QAA14534
	for <acpi-jp@jp.freebsd.org>; Sat, 20 May 2000 16:35:30 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
To: acpi-jp@jp.freebsd.org
In-Reply-To: <200001101957.EAA20279@tasogare.imasy.or.jp>
References: <200001101957.EAA20279@tasogare.imasy.or.jp>
X-Mailer: Mew version 1.94.1 on Emacs 19.34 / Mule 2.3 (SUETSUMUHANA)
Mime-Version: 1.0
Content-Type: Text/Plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
Message-Id: <20000520163530P.iwasaki@jp.FreeBSD.org>
Date: Sat, 20 May 2000 16:35:30 +0900
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Dispatcher: imput version 20000228(IM140)
Lines: 379
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+000315
X-Sequence: acpi-jp 301
Subject: [acpi-jp 301] Re: over 32 bit region I/O
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

> 3110CT.dsdt.dat $B$N(B \PRS $B$r%F%9%H$7$F$$$F5$IU$$$?$N$G$9$,!"(B
> parse $BCf$O(B 32 $B%S%C%H$r1[$($k(B Field $B$N(B I/O $B$r(B $B$d$i$:$K(B aml_regfield $B7?$J$k(B
> $B$b$N$K>pJs$r5M$a9~$s$G$*$$$F!"(BStore $B$NCJ3,$G<B:]$N(B I/O $B$r=hM}$9$k(B
> $B$h$&$K$9$k$N$O$$$+$,$G$7$g$&(B?

$B$3$NOC$9$C$+$jK:$l$F$$$?$N$G$9$,(B (^^;$B!"$H$j$"$($:(B
buffer <-> field $B4V$N(B I/O $B$,$G$-$?$N$G%Q%C%A$rN.$7$F$*$-$^$9!#(B
# bufferfield $B$K4X$7$F$O(B takawata $B$5$s$K$*G$$;$7$F$$$$(B?

$BL@F|Lk$"$?$j(B commit $B$G$9!#(B

Index: amlmem.c
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/amlmem.c,v
retrieving revision 1.7
diff -u -r1.7 amlmem.c
--- amlmem.c	2000/03/21 19:30:11	1.7
+++ amlmem.c	2000/03/22 13:05:11
@@ -52,6 +52,7 @@
 MEMMAN_INITIALSTORAGE_DESC(struct aml_name, _aml_name_storage);
 MEMMAN_INITIALSTORAGE_DESC(struct aml_name_group, _aml_name_group_storage);
 MEMMAN_INITIALSTORAGE_DESC(struct aml_objref, _aml_objref_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_regfield, _aml_regfield_storage);
 MEMMAN_INITIALSTORAGE_DESC(struct aml_environ, _aml_environ_storage);
 MEMMAN_INITIALSTORAGE_DESC(struct aml_local_stack, _aml_objectptr_storage);
 
@@ -72,13 +73,14 @@
 	MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name), _aml_name_storage),
 	MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name_group), _aml_name_group_storage),
 	MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_objref), _aml_objref_storage),
+ 	MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_regfield), _aml_regfield_storage),
 	MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_environ), _aml_environ_storage),
 	MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_local_stack), _aml_objectptr_storage),
 };
 
 struct memman_histogram aml_histogram[MEMMAN_HISTOGRAM_SIZE];
 
-static struct memman _aml_memman = MEMMAN_MEMMANAGER_DESC(aml_blockman, 18,
+static struct memman _aml_memman = MEMMAN_MEMMANAGER_DESC(aml_blockman, 19,
 						     aml_histogram, 1);
 
 struct memman *aml_memman = &_aml_memman;
Index: amlmem.h
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/amlmem.h,v
retrieving revision 1.6
diff -u -r1.6 amlmem.h
--- amlmem.h	2000/03/21 19:30:11	1.6
+++ amlmem.h	2000/03/22 13:03:02
@@ -51,6 +51,7 @@
 	memid_aml_name,
 	memid_aml_name_group,
 	memid_aml_objref,
+	memid_aml_regfield,
 	memid_aml_environ,
 	memid_aml_local_stack,
 };
Index: evalobj.c
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/evalobj.c,v
retrieving revision 1.10
diff -u -r1.10 evalobj.c
--- evalobj.c	2000/03/20 14:46:30	1.10
+++ evalobj.c	2000/03/22 13:03:02
@@ -64,7 +64,7 @@
 	field=&name->property->field;
 	oname=env->curname;
 	if(field->bitlen>=32){
-		env->wobj.type=aml_t_null;/*Not impremented yet*/
+		env->wobj.type=aml_t_regfield;
 	}else{
 		env->wobj.type=aml_t_num;
 	}
@@ -81,11 +81,19 @@
 			return NULL;
 		}
 		or=&wname->property->opregion;
-		DPRINT("[read(From%d , 0x%x)]",
-		    or->space,or->offset+field->bitoffset/8);
-		env->wobj.type = aml_t_num;
-		env->wobj.num.number = acpi_region_read(or->space, field->flags,
-		    or->offset, field->bitoffset, field->bitlen);
+		if (env->wobj.type == aml_t_regfield) {
+			env->wobj.regfield.space = or->space;
+			env->wobj.regfield.flags = field->flags;
+			env->wobj.regfield.offset = or->offset;
+			env->wobj.regfield.bitoffset = field->bitoffset;
+			env->wobj.regfield.bitlen = field->bitlen;
+		} else {
+			DPRINT("[read(From%d , 0x%x)]",
+			    or->space,or->offset+field->bitoffset/8);
+			env->wobj.type = aml_t_num;
+			env->wobj.num.number = acpi_region_read(or->space,
+			    field->flags, or->offset, field->bitoffset, field->bitlen);
+		}
 	}else if(field->f.ftype==f_t_index){
 		union aml_object tobj;
 		wname=acpi_search_name(env,field->f.ifld.indexname);
Index: obj.c
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/obj.c,v
retrieving revision 1.6
diff -u -r1.6 obj.c
--- obj.c	2000/03/21 19:30:11	1.6
+++ obj.c	2000/03/22 13:07:19
@@ -65,6 +65,8 @@
 			ret->str.string = memman_alloc_flexsize(aml_memman,
 			    strlen(orig->str.string) + 1);
 			strcpy(orig->str.string, ret->str.string);	
+		} else if (orig->type == aml_t_regfield) {
+ 			*ret = env->wobj;
 		}
 	}else{
 		printf ("%s:%d \n", __FILE__, __LINE__);
Index: obj.h
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/obj.h,v
retrieving revision 1.7
diff -u -r1.7 obj.h
--- obj.h	2000/03/21 19:30:11	1.7
+++ obj.h	2000/03/22 13:03:02
@@ -31,7 +31,8 @@
 #include <sys/queue.h>
 struct aml_environ;
 enum aml_objtype {
-	aml_t_namestr = -2,
+	aml_t_namestr = -3,
+	aml_t_regfield,
 	aml_t_objref,
 	aml_t_null = 0,
 	aml_t_num,
@@ -152,6 +153,14 @@
 	/* if negative value, not ready to dereference for element access. */
 	unsigned	deref;	/* indicates whether dereffenced or not */
 };
+struct aml_regfield {
+	enum aml_objtype type;
+	int		space;
+	u_int32_t	flags;
+	int		offset;
+	int		bitoffset;
+	int		bitlen;
+};
 union aml_object {
 	enum aml_objtype type;
 	struct aml_num  num;
@@ -167,6 +176,7 @@
 	struct aml_package package;
 	struct aml_string str;
 	struct aml_objref objref;
+	struct aml_regfield regfield;
 };
 
 union aml_object * acpi_copy_object(struct aml_environ *,union aml_object *);
Index: parse.c
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/parse.c,v
retrieving revision 1.18
diff -u -r1.18 parse.c
--- parse.c	2000/03/20 14:46:30	1.18
+++ parse.c	2000/03/22 19:57:55
@@ -1306,6 +1306,12 @@
 			printf("???");
 			break;
 		}
+		if (tmpobj->type == aml_t_regfield) {
+			tmpobj->type=aml_t_null;
+			acpi_free_object(&tmpobj);
+			aname->property = tmpobj = acpi_copy_object(env,
+			    distname1->property);
+		}
 		break;
 
 	case 0x71:		/* RefOfOp */
Index: region.c
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/region.c,v
retrieving revision 1.6
diff -u -r1.6 region.c
--- region.c	2000/01/11 21:04:31	1.6
+++ region.c	2000/05/19 16:42:45
@@ -330,6 +330,54 @@
 	return state;
 }
 
+static int
+acpi_simulate_region_io_buffer(int io, int regtype, u_int32_t flags,
+    u_int8_t *buffer, u_int32_t baseaddr, u_int32_t bitoffset, u_int32_t bitlen)
+{
+	u_int32_t	addr, byteoffset, bytelen;
+	u_int8_t	val = 0;
+	u_int8_t	offsetlow, offsethigh = 0;
+	int		state = 0, i;
+
+	byteoffset = bitoffset / 8;
+	bytelen = bitlen / 8 + ((bitlen % 8)? 1 : 0);
+	addr = baseaddr + byteoffset;
+	offsetlow = bitoffset % 8;
+	assert(offsetlow == 0);
+
+	if (bytelen > 1) {
+		offsethigh = (bitlen - (8 - offsetlow)) % 8;
+	}
+	assert(offsethigh == 0);
+
+	for (i = bytelen; i > 0; i--, addr++) {
+
+		switch (io) {
+		case ACPI_REGION_INPUT:
+			val = 0;
+			state = acpi_simulate_regcontent_read(regtype, addr, &val);
+			if (state == -1) {
+				goto finish;
+			}
+
+			buffer[bytelen - i] = val;
+			break;
+
+		case ACPI_REGION_OUTPUT:
+			val = buffer[bytelen - i];
+			state = acpi_simulate_regcontent_write(regtype,
+			    addr, &val);
+			if (state == -1) {
+				goto finish;
+			}
+
+			break;
+		}
+	}
+finish:
+	return state;
+}
+
 static u_int32_t
 acpi_simulate_region_read(int regtype, u_int32_t flags, u_int32_t addr,
     u_int32_t bitoffset, u_int32_t bitlen)
@@ -346,6 +394,20 @@
 }
 
 int
+acpi_simulate_region_read_into_buffer(int regtype, u_int32_t flags,
+    u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen, u_int8_t *buffer)
+{
+	int		state;
+
+	DPRINT("\n[acpi_region_read_into_buffer(%d, %d, 0x%x, 0x%x, 0x%x)]\n",
+	    regtype, flags, addr, bitoffset, bitlen);
+	state = acpi_simulate_region_io_buffer(ACPI_REGION_INPUT, regtype, flags,
+	    buffer, addr, bitoffset, bitlen);
+	assert(state != -1);
+	return state;
+}
+
+int
 acpi_simulate_region_write(int regtype, u_int32_t flags, u_int32_t value,
     u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
 {
@@ -359,6 +421,20 @@
 	return state;
 }
 
+int
+acpi_simulate_region_write_from_buffer(int regtype, u_int32_t flags,
+    u_int8_t *buffer, u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
+{
+	int		state;
+
+	DPRINT("\n[acpi_region_write_from_buffer(%d, %d, 0x%x, 0x%x, 0x%x)]\n",
+	    regtype, flags, addr, bitoffset, bitlen);
+	state = acpi_simulate_region_io_buffer(ACPI_REGION_OUTPUT, regtype,
+	    flags, buffer, addr, bitoffset, bitlen);
+	assert(state != -1);
+	return state;
+}
+
 u_int32_t
 acpi_region_read(int regtype, u_int32_t flags, u_int32_t addr,
     u_int32_t bitoffset, u_int32_t bitlen)
@@ -368,11 +444,27 @@
 }
 
 int
+acpi_region_read_into_buffer(int regtype, u_int32_t flags, u_int32_t addr,
+    u_int32_t bitoffset, u_int32_t bitlen, u_int8_t *buffer)
+{
+	return acpi_simulate_region_read_into_buffer(regtype, flags, addr,
+	    bitoffset, bitlen, buffer);
+}
+
+int
 acpi_region_write(int regtype, u_int32_t flags, u_int32_t value,
     u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
 {
 	return acpi_simulate_region_write(regtype, flags, value, addr,
 	    bitoffset, bitlen);
+}
+
+int
+acpi_region_write_from_buffer(int regtype, u_int32_t flags, u_int8_t *buffer,
+    u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
+{
+	return acpi_simulate_region_write_from_buffer(regtype, flags, buffer,
+	    addr, bitoffset, bitlen);
 }
 
 void
Index: region.h
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/region.h,v
retrieving revision 1.3
diff -u -r1.3 region.h
--- region.h	2000/03/21 19:30:11	1.3
+++ region.h	2000/03/22 13:10:49
@@ -37,6 +37,10 @@
 				 int, int);
 int		acpi_region_write(int, u_int32_t, int,
     				  int, int, int);
+int		acpi_region_read_into_buffer(int, u_int32_t, u_int32_t,
+					     u_int32_t, u_int32_t, u_int8_t *);
+int		acpi_region_write_from_buffer(int, u_int32_t, u_int8_t *,
+					      u_int32_t, u_int32_t, u_int32_t);
 
 void		acpi_simulation_regdump(const char *);
 extern int     acpi_debug_prompt_regoutput;
Index: store.c
===================================================================
RCS file: /home/cvs/ACPI/util/acpiconf/store.c,v
retrieving revision 1.8
diff -u -r1.8 store.c
--- store.c	2000/03/20 14:46:30	1.8
+++ store.c	2000/05/20 07:01:29
@@ -59,9 +59,21 @@
 			return ;
 		}
 		or=&wname->property->opregion;
-		DPRINT("[write(From%d, 0x%x, 0x%x)]",or->space, obj->num.number, or->offset+field->bitoffset/8);
-		acpi_region_write(or->space, field->flags, obj->num.number,
-		    or->offset, field->bitoffset, field->bitlen);
+		switch (obj->type) {
+		case aml_t_num:
+			DPRINT("[write(From%d, 0x%x, 0x%x)]",
+			    or->space, obj->num.number, or->offset+field->bitoffset/8);
+			acpi_region_write(or->space, field->flags, obj->num.number,
+			    or->offset, field->bitoffset, field->bitlen);
+			break;
+		case aml_t_buffer:
+			acpi_region_write_from_buffer(or->space, field->flags, obj->buffer.data,
+			    or->offset, field->bitoffset, field->bitlen);
+			break;
+		default:
+			DPRINT("acpi_store_to_fieldname: Inappropreate Type of src object");
+			break;
+		}
 	}else if(field->f.ftype==f_t_index){
 		union aml_object tobj;
 		wname=acpi_search_name(env,field->f.ifld.indexname);
@@ -109,6 +121,13 @@
 		bcopy(obj->buffer.data, buf->buffer.data, size);
 		break;
 
+	case aml_t_regfield:
+		acpi_region_read_into_buffer(obj->regfield.space,
+		    obj->regfield.flags, obj->regfield.offset, 
+		    obj->regfield.bitoffset, obj->regfield.bitlen, 
+		    buf->buffer.data);
+		break;
+
 	default:
 		goto not_yet;
 	}
@@ -258,6 +277,7 @@
 		acpi_store_to_object(env, obj, name->property);
 		break;
 	}
+	env->wobj = *name->property;
 }
 
 

