summaryrefslogtreecommitdiffstats
path: root/sys/i386/apm/apm.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1994-12-16 06:16:30 +0000
committerphk <phk@FreeBSD.org>1994-12-16 06:16:30 +0000
commitd0387a375e0c8e6ee97d48f7ce3c92f8303b9133 (patch)
tree4565dee3c477fa40e2fad901aaa1dcc8e6b524dc /sys/i386/apm/apm.c
parent1fd36e21b20001d7217b86534d1accb7ceaf7a69 (diff)
downloadFreeBSD-src-d0387a375e0c8e6ee97d48f7ce3c92f8303b9133.zip
FreeBSD-src-d0387a375e0c8e6ee97d48f7ce3c92f8303b9133.tar.gz
Be much more carefull about what we leave in unused registers when we call
the APM-bios. This stabilizes a couple of APM bioses quite a bit. They all make the mistake of going into 16-bit mode, without clearing the top half of the 32bit registers. Later they do a | movw %si,$0x7331 | movw %ax,0x6(%si) or something along those lines and crash and burn, because their segment is already relocated, so adding 0xf0171ce9 to the base of it is bad news. At least SystemSoft is guilty of this bummer.
Diffstat (limited to 'sys/i386/apm/apm.c')
-rw-r--r--sys/i386/apm/apm.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/i386/apm/apm.c b/sys/i386/apm/apm.c
index d419da4..99c3582 100644
--- a/sys/i386/apm/apm.c
+++ b/sys/i386/apm/apm.c
@@ -13,7 +13,7 @@
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
- * $Id: apm.c,v 1.6 1994/11/07 04:23:58 phk Exp $
+ * $Id: apm.c,v 1.7 1994/11/15 14:09:18 bde Exp $
*/
#include "apm.h"
@@ -92,11 +92,18 @@ apm_int(u_long *eax,u_long *ebx,u_long *ecx)
u_long cf;
__asm ("pushl %%ebp
pushl %%edx
+ pushl %%esi
+ pushl %%edi
xorl %3,%3
+ movl %%edi,%3
+ movl %%esi,%3
lcall _apm_addr
jnc 1f
incl %3
- 1: popl %%edx
+ 1:
+ popl %%edi
+ popl %%esi
+ popl %%edx
popl %%ebp"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=D" (cf)
: "0" (*eax), "1" (*ebx), "2" (*ecx)
@@ -175,6 +182,8 @@ apm_getevent(void)
eax = (APM_BIOS<<8) | APM_GETPMEVENT;
+ ebx = 0;
+ ecx = 0;
if (apm_int(&eax,&ebx,&ecx))
return PMEV_NOEVENT;
@@ -243,6 +252,7 @@ apm_get_info(apm_info_t aip)
eax = (APM_BIOS<<8)|APM_GETPWSTATUS;
ebx = PMDV_ALLDEV;
+ ecx = 0;
if (apm_int(&eax,&ebx,&ecx))
return 1;
OpenPOWER on IntegriCloud