From owner-acpi-jp@jp.freebsd.org  Tue Jul  4 01:26:39 2000
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id BAA03209;
	Tue, 4 Jul 2000 01:26:39 +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 BAA03204
	for <acpi-jp@jp.freebsd.org>; Tue, 4 Jul 2000 01:26:38 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
Received: from localhost (isdnb19.imasy.or.jp [202.227.24.147])
	by tasogare.imasy.or.jp (8.10.1+3.3W/3.7W-tasogare/smtpfeed 1.07) with ESMTP id e63GQYp27100
	for <acpi-jp@jp.freebsd.org>; Tue, 4 Jul 2000 01:26:34 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
To: acpi-jp@jp.freebsd.org
In-Reply-To: <20000703195851B.iwasaki@jp.FreeBSD.org>
References: <20000703101319G.iwasaki@jp.FreeBSD.org>
	<20000703161039X.yokoyama@o3.otc.ogis-ri.co.jp>
	<20000703195851B.iwasaki@jp.FreeBSD.org>
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: <20000704012634J.iwasaki@jp.FreeBSD.org>
Date: Tue, 04 Jul 2000 01:26:34 +0900
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Dispatcher: imput version 20000228(IM140)
Lines: 508
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+000315
X-Sequence: acpi-jp 457
Subject: [acpi-jp 457] Re: merging to FreeBSD
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

> $B$3$A$i$K$b(B S1 $B$XA+0\$G$-$J$$(B PORTEGE 3110CT $B$,$"$k$N$G!"$$$m$$$m;n$7$F$_$^$9!#(B
> $BA+0\=hM}$N8e!"(BWAK_STS $B$r8+D%$k%k!<%W$,I,MW$_$?$$$G$9$,!"$=$l$G$b$&$^$/(B
> $B5/$->e$,$l$F$$$J$$$h$&$G$9(B...

$B$I$&$b(B PORTEGE 3110CT $B$G$O(B S[135] $B6&$K(B {7, 0} $B$H$$$&CM$r;H$&$?$a$+!"(B
S1 $BA+0\$G$b(B wakeup vector $BEy$N@_Dj$,I,MW$C$]$$$G$9!#B>$N5!<o$@$H(B
$B$3$l$G%$%1$k2DG=@-$,9b$$$G$9!#(B
$B$^$?!"?7$7$$(B config option, AML_DEBUG $B$rDI2C$7!"%G%P%C%0=PNO@)8f$r(B
$B$A$g$C$H$^$H$b$K$7$^$7$?!#$D$$$G$K(B aml_region $B$NJ}$b(B 1, 2, 4 $B%P%$%H(B
I/O $B$K$h$k8zN(2=$r$d$C$F$_$^$7$?$N$G!";n$7$F$_$F$/$@$5$$!#(B
$B2PMKF|$N?<Lk$K0lC6(B commit $B$7$F$_$^$9!#(B

Index: conf/options.i386
===================================================================
RCS file: /home/cvs/ACPI/sys/conf/options.i386,v
retrieving revision 1.2
diff -u -r1.2 options.i386
--- conf/options.i386	2000/05/29 16:08:00	1.2
+++ conf/options.i386	2000/07/03 15:00:17
@@ -196,6 +196,7 @@
 # ACPI Debug options
 # -------------------------------
 ACPI_DEBUG		opt_acpi.h
+AML_DEBUG		opt_acpi.h
 # -------------------------------
 # EOF
 # -------------------------------
Index: i386/acpi/acpi.c
===================================================================
RCS file: /home/cvs/ACPI/sys/i386/acpi/acpi.c,v
retrieving revision 1.16
diff -u -r1.16 acpi.c
--- i386/acpi/acpi.c	2000/06/30 15:18:40	1.16
+++ i386/acpi/acpi.c	2000/07/03 15:59:14
@@ -97,6 +97,7 @@
 	struct FACS    *facs;
 	struct acpi_system_state_package system_state_package;
 	int		system_state_initialized;
+	int		broken_wakeuplogic;
 } acpi_softc_t;
 
 /* Character device stuff */
@@ -155,7 +156,11 @@
 static void acpi_soft_off(void *data,int howto);
 
 /* for debugging */
+#ifdef ACPI_DEBUG
+static	int	acpi_debug = 1;
+#else	/* !ACPI_DEBUG */
 static	int	acpi_debug = 0;
+#endif	/* ACPI_DEBUG */
 SYSCTL_INT(_debug, OID_AUTO, acpi_debug, CTLFLAG_RW, &acpi_debug, 1, "");
 
 #define ACPIPRINTF(args...)	printf("acpi0: " args)
@@ -276,6 +281,7 @@
 {
 	char	namestr[5];
 	int	i;
+	int	debug;
 	struct	aml_name *newname, *sname;
 	union	aml_object *spkg;
 	struct	aml_name_group *newgrp;
@@ -303,11 +309,18 @@
 	env.end = (u_int8_t *)dsdp + dsdp->len;
 	env.curname = aml_get_rootname();
 
+	debug = aml_debug;
+	aml_debug = 0;
+
 	aml_local_stack_push(aml_local_stack_create());
 	aml_parse_objectlist(&env, 0);
 	aml_local_stack_delete(aml_local_stack_pop());
 
-	aml_showtree(aml_get_rootname(), 0);
+	aml_debug = debug;
+
+	if (aml_debug) {
+		aml_showtree(aml_get_rootname(), 0);
+	}
 
 	sc->system_state_initialized = 1;
 	for (i = 0; i < 6; i++) {
@@ -331,8 +344,10 @@
 		}
 		ssp.mode[i].slp_typ_a = spkg->package.objects[0]->num.number;
 		ssp.mode[i].slp_typ_b = spkg->package.objects[1]->num.number;
-		ACPIPRINTF("%s : [%d, %d]\n", namestr,
-		    ssp.mode[i].slp_typ_a, ssp.mode[i].slp_typ_b);
+		if (acpi_debug) {
+			ACPIPRINTF("%s : [%d, %d]\n", namestr,
+			    ssp.mode[i].slp_typ_a, ssp.mode[i].slp_typ_b);
+		}
 	}
 	sc->system_state_package = ssp;
 
@@ -389,6 +404,17 @@
 #define	ACPI_PM1_PWRBTN_EN		0x0100
 #define	ACPI_PM1_SLPBTN_EN		0x0200
 #define	ACPI_PM1_RTC_EN			0x0400
+/* these bits are for status only */
+#define	ACPI_PM1_BM_STS			0x0010
+#define	ACPI_PM1_WAK_STS		0x8000
+
+#define	ACPI_CNT_SCI_EN			0x0001
+#define	ACPI_CNT_BM_RLD			0x0002
+#define	ACPI_CNT_GBL_RLS		0x0004
+#define	ACPI_CNT_SLP_TYPX		0x1c00
+#define	ACPI_CNT_SLP_EN			0x2000
+
+#define	ACPI_CNT_SET_SLP_TYP(x)		(x << 10)
 
 /* Fixed ACPI Description Table Fixed Feature Flags (5.2.5 Table 5-6) */
 #define ACPI_FACP_FLAGS_WBINVD		0x00000001
@@ -408,26 +434,75 @@
 static void
 acpi_trans_sleeping_state(acpi_softc_t *sc, u_int8_t state)
 {
-	u_int32_t	val_a, val_b;
 	u_int8_t	slp_typx;
+	u_int32_t	val_a, val_b;
+	int		debug, count;
+	u_long		ef;
 
+	ef = read_eflags();
 	disable_intr();
-	/* clear WAK_STS bit by writing a one */
-	acpi_io_pm1_status(sc, ACPI_REGISTERS_INPUT,
-			   &val_a, &val_b);
-	val_a = val_b = 0;
-	val_a |= 0x1 << 15;		/* WAK_STS */
-	val_b |= 0x1 << 15;		/* WAK_STS */
-	acpi_io_pm1_status(sc, ACPI_REGISTERS_OUTPUT,
-			   &val_a, &val_b);
 
+	if (state > 0) {
+		/* clear WAK_STS bit by writing a one */
+		acpi_io_pm1_status(sc, ACPI_REGISTERS_INPUT,
+				   &val_a, &val_b);
+		if ((val_a | val_b) & ACPI_PM1_WAK_STS) {
+			sc->broken_wakeuplogic = 0;
+		} else {
+			ACPIPRINTF("wake-up logic seems broken, "
+			    "this may cause troubles on wakeup\n");
+			sc->broken_wakeuplogic = 1;
+		}
+		val_a = val_b = 0;
+		val_a = ACPI_PM1_WAK_STS;
+		val_b = ACPI_PM1_WAK_STS;
+		acpi_io_pm1_status(sc, ACPI_REGISTERS_OUTPUT,
+				   &val_a, &val_b);
+	}
+
+	acpi_io_pm1_control(sc, ACPI_REGISTERS_INPUT,
+			   &val_a, &val_b);
+	val_a  &= ~(ACPI_CNT_SLP_TYPX);
+	val_b  &= ~(ACPI_CNT_SLP_TYPX);
 	slp_typx = sc->system_state_package.mode[state].slp_typ_a;
-	val_a  = slp_typx << 10 | 0x1 << 13;	/* SLP_TYPx | SLP_EN */
+	val_a  |= ACPI_CNT_SET_SLP_TYP(slp_typx) | ACPI_CNT_SLP_EN;
 	slp_typx = sc->system_state_package.mode[state].slp_typ_b;
-	val_b  = slp_typx << 10 | 0x1 << 13;	/* SLP_TYPx | SLP_EN */
+	val_b  |= ACPI_CNT_SET_SLP_TYP(slp_typx) | ACPI_CNT_SLP_EN;
 	acpi_io_pm1_control(sc, ACPI_REGISTERS_OUTPUT,
 			   &val_a, &val_b);
-	enable_intr();
+
+	if (state == 0) {
+		goto sleep_done;
+	}
+
+	/*
+	 * wait for WAK_STS bit
+	 */
+	debug = acpi_debug;	/* Save debug level */
+	acpi_debug = 0;		/* Shut up */
+
+	count = 0;
+	for (;;) {
+		acpi_io_pm1_status(sc, ACPI_REGISTERS_INPUT,
+				   &val_a, &val_b);
+		if ((val_a | val_b) & ACPI_PM1_WAK_STS) {
+			break;
+		}
+		/* XXX
+		 * some BIOSes doesn't set WAK_STS at all,
+		 * give up waiting for wakeup if timeout...
+		 */
+		if (sc->broken_wakeuplogic) {
+			if (count++ >= 100) {
+				break;		/* giving up */
+			}
+		}
+		DELAY(10*1000);			/* 0.01 sec */
+	}
+	acpi_debug = debug;	/* Restore debug level */
+
+sleep_done:
+	write_eflags(ef);
 }
 
 static void
@@ -436,7 +511,7 @@
 	acpi_softc_t	*sc = (acpi_softc_t *) data;
 
 	/* wait 1sec before turning off the system power */
-	DELAY(1000000L);
+	DELAY(1000*1000);
 	acpi_trans_sleeping_state(sc, 5);
 }
 
@@ -461,9 +536,10 @@
 	}
 
 	/*
-	 * XXX currently supported S1 and S5 only.
+	 * XXX currently supported S0, S1 and S5 only.
 	 */
 	switch (state) {
+	case 0:
 	case 1:
 		acpi_trans_sleeping_state(sc, state);
 		acpi_execute_wak(sc, state);
@@ -622,9 +698,6 @@
 	       acpi_rsdp, oemstring, acpi_rsdp->addr);
 
 	device_set_desc(dev, oemstring);
-#ifdef ACPI_DEBUG
-	acpi_debug = 1;
-#endif
 	return (0);
 }
 
@@ -775,29 +848,60 @@
  * ACPI Registers I/O
  */
 
-static void
+static __inline void
 acpi_registers_input(u_int32_t ioaddr, u_int32_t *value, u_int32_t size)
 {
-	int		i;
 	u_int32_t	val;
 
-	val = 0;
-	for (i = size - 1; i >= 0; i--) {
-		val = (val << 8) | OsdIn8(ioaddr + i);
+	switch (size) {
+	case 1:
+		val = OsdIn8(ioaddr);
+		break;
+	case 2:
+		val = OsdIn16(ioaddr);
+		break;
+	case 3:
+		val = OsdIn8(ioaddr);
+		val |= OsdIn8(ioaddr + 1) << 8;
+		val |= OsdIn8(ioaddr + 2) << 16;
+		break;
+	case 4:
+		val = OsdIn32(ioaddr);
+		break;
+	default:
+		ACPIPRINTF("acpi_registers_input(): invalid size\n");
+		val = 0;
+		break;
 	}
+
 	*value = val;
 }
 
-static void
+static __inline void
 acpi_registers_output(u_int32_t ioaddr, u_int32_t *value, u_int32_t size)
 {
-	int		i;
 	u_int32_t	val;
 
 	val = *value;
-	for (i = 0; i < size; i++) {
-		OsdOut8(ioaddr + i, val & 0xff);
-		val >>= 8;
+
+	switch (size) {
+	case 1:
+		OsdOut8(ioaddr, val);
+		break;
+	case 2:
+		OsdOut16(ioaddr, val);
+		break;
+	case 3:
+		OsdOut8(ioaddr, val & 0xff);
+		OsdOut8(ioaddr + 1, (val >> 8) & 0xff);
+		OsdOut8(ioaddr + 2, (val >> 16) & 0xff);
+		break;
+	case 4:
+		OsdOut32(ioaddr, val);
+		break;
+	default:
+		ACPIPRINTF("acpi_registers_output(): invalid size\n");
+		break;
 	}
 }
 
Index: i386/acpi/aml/aml_common.c
===================================================================
RCS file: /home/cvs/ACPI/sys/i386/acpi/aml/aml_common.c,v
retrieving revision 1.5
diff -u -r1.5 aml_common.c
--- i386/acpi/aml/aml_common.c	2000/06/23 00:43:04	1.5
+++ i386/acpi/aml/aml_common.c	2000/07/03 15:23:55
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <unistd.h>
 #else /* _KERNEL */
+#include "opt_acpi.h"
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
@@ -51,7 +52,11 @@
 #include <i386/acpi/aml/aml_store.h>
 
 /* for debugging */
+#ifdef AML_DEBUG
+int	aml_debug = 1;
+#else	/* !AML_DEBUG */
 int	aml_debug = 0;
+#endif	/* AML_DEBUG */
 #ifdef _KERNEL
 SYSCTL_INT(_debug, OID_AUTO, aml_debug, CTLFLAG_RW, &aml_debug, 1, "");
 #endif /* _KERNEL */
@@ -139,32 +144,32 @@
 	int	debug;
 	int	i;
 
-	debug = aml_debug;
-	aml_debug = 1;
 	if (obj == NULL) {
 		printf("NO object\n");
 		return;
 	}
+	debug = aml_debug;
+	aml_debug = 1;
 	switch (obj->type) {
 	case aml_t_num:
 		printf("Num:0x%x\n", obj->num.number);
-		return;
+		break;
 	case aml_t_processor:
 		printf("Processor:No %d,Port 0x%x length 0x%x\n",
 		    obj->proc.id, obj->proc.addr, obj->proc.len);
-		return;
+		break;
 	case aml_t_mutex:
 		printf("Mutex:Level %d\n", obj->mutex.level);
-		return;
+		break;
 	case aml_t_powerres:
 		printf("PowerResource:Level %d Order %d\n",
 		    obj->pres.level, obj->pres.order);
-		return;
+		break;
 	case aml_t_opregion:
 		printf("OprationRegion:Busspace%d, Offset 0x%x Length 0x%x\n",
 		    obj->opregion.space, obj->opregion.offset,
 		    obj->opregion.length);
-		return;
+		break;
 	case aml_t_field:
 		printf("Fieldelement:flag 0x%x offset 0x%x len 0x%x {",
 		    obj->field.flags, obj->field.bitoffset,
Index: i386/acpi/aml/aml_evalobj.c
===================================================================
RCS file: /home/cvs/ACPI/sys/i386/acpi/aml/aml_evalobj.c,v
retrieving revision 1.19
diff -u -r1.19 aml_evalobj.c
--- i386/acpi/aml/aml_evalobj.c	2000/06/30 15:18:45	1.19
+++ i386/acpi/aml/aml_evalobj.c	2000/07/03 14:50:08
@@ -254,7 +254,9 @@
 			aml_local_stack_delete(aml_local_stack_pop());
 			goto out;
 		}
-		aml_showobject(obj);
+		if (aml_debug) {
+			aml_showobject(obj);
+		}
 
 		if (tmp)
 			tmp->property = NULL;
@@ -358,7 +360,9 @@
 		}
 		aml_local_stack_push(stack);
 		obj = aml_eval_name(env, tmp = aml_execute_method(env));
-		aml_showtree(name, 0);
+		if (aml_debug) {
+			aml_showtree(name, 0);
+		}
 
 		if (tmp)
 			tmp->property = NULL;
Index: i386/acpi/aml/aml_region.c
===================================================================
RCS file: /home/cvs/ACPI/sys/i386/acpi/aml/aml_region.c,v
retrieving revision 1.5
diff -u -r1.5 aml_region.c
--- i386/acpi/aml/aml_region.c	2000/06/30 15:18:45	1.5
+++ i386/acpi/aml/aml_region.c	2000/07/03 13:32:21
@@ -86,6 +86,93 @@
 	if (regtype == 0) {
 		OsdMapMemory((void *)addr, bytelen, (void **)&vaddr);
 	}
+
+	/* simple I/O ? */
+	if (offsetlow == 0 && offsethigh == 0 &&
+	    (bitlen == 8 || bitlen == 16 || bitlen == 32)) {
+		switch (io) {
+		case AML_REGION_INPUT:
+			switch (regtype) {
+			case 0:
+				switch (bitlen) {
+				case 8:
+					value = *(volatile u_int8_t *)(vaddr);
+					value &= 0xff;
+					break;
+				case 16:
+					value = *(volatile u_int16_t *)(vaddr);
+					value &= 0xffff;
+					break;
+				case 32:
+					value = *(volatile u_int32_t *)(vaddr);
+					break;
+				}
+				break;
+			case 1:
+				switch (bitlen) {
+				case 8:
+					value = OsdIn8(addr);
+					value &= 0xff;
+					break;
+				case 16:
+					value = OsdIn16(addr);
+					value &= 0xffff;
+					break;
+				case 32:
+					value = OsdIn32(addr);
+					break;
+				}
+				break;
+			default:
+				printf("aml_region_io_system: not supported yet (%d)\n",
+				    regtype);
+				value = 0;
+				break;
+			}
+			*valuep = value;
+			break;
+		case AML_REGION_OUTPUT:
+			switch (regtype) {
+			case 0:
+				switch (bitlen) {
+				case 8:
+					value &= 0xff;
+					*(volatile u_int8_t *)(vaddr) = value;
+					break;
+				case 16:
+					value &= 0xffff;
+					*(volatile u_int16_t *)(vaddr) = value;
+					break;
+				case 32:
+					*(volatile u_int32_t *)(vaddr) = value;
+					break;
+				}
+				break;
+			case 1:
+				switch (bitlen) {
+				case 8:
+					value &= 0xff;
+					OsdOut8(addr, value);
+					break;
+				case 16:
+					value &= 0xffff;
+					OsdOut16(addr, value);
+					break;
+				case 32:
+					OsdOut32(addr, value);
+					break;
+				}
+				break;
+			default:
+				printf("aml_region_io_system: not supported yet (%d)\n",
+				    regtype);
+				break;
+			}
+			break;
+		}
+		goto io_done;
+	}
+
 	for (i = 0; i < bytelen; i++) {
 		/* XXX */
 		switch (regtype) {
@@ -173,6 +260,7 @@
 		}
 	}
 
+io_done:
 	if (regtype == 0) {
 		OsdUnMapMemory((void *)vaddr, bytelen);
 	}
